Welcome, guest | Sign In | My Account | Store | Cart

Checking for a keypress without stop the execution of the script (unix way).

Python, 40 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/python

import os, sys
import tty
from select import select

class NotTTYException(Exception): pass

class TerminalFile:
    def __init__(self,infile):
        if not infile.isatty():
            raise NotTTYException()
        self.file=infile

        #prepare for getch
        self.save_attr=tty.tcgetattr(self.file)
        newattr=self.save_attr[:]
        newattr[3] &= ~tty.ECHO & ~tty.ICANON
        tty.tcsetattr(self.file, tty.TCSANOW, newattr)

    def __del__(self):
        #restoring stdin
        import tty  #required this import here
        tty.tcsetattr(self.file, tty.TCSADRAIN, self.save_attr)

    def getch(self):
        if select([self.file],[],[],0)[0]:
            c=self.file.read(1)
        else:
            c=''
        return c

if __name__=="__main__":
    s=TerminalFile(sys.stdin)
    print "Press q to quit..."
    i=0
    while s.getch()!="q":
        sys.stdout.write("%08d\r"%i)
        i+=1
    print "-- END --"

This script must be executed into a terminal (unix/linux). It uses the module 'select' to test stdin before to do the reading. All the code is encapsulated into a object in order to restore the terminal when the object gets delete (eg: at the gc loop). That code is based in the code due Andrew Kuchling. Thanks to the python-es list, in concrete to Marcos Sánchez Provencio for the idea.

1 comment

privman 14 years, 1 month ago  # | flag

Thanks Chema, This is really useful. You saved me probably a few hours of work, since I have no background in working with Terminals. I just copied your code into a py file and I'm using it in my code. Works great :)

Created by Chema Cortes on Thu, 5 Jun 2003 (PSF)
Python recipes (4591)
Chema Cortes's recipes (1)

Required Modules

Other Information and Tasks