Continuous loop and exit python

I have a script that runs continuously on call and checks my gmail inbox every 5 minutes. To run it every 5 minutes, I use the time.sleep () function. However, I would like the user to end the script anytime he presses q, which seems impossible when using time.sleep (). Any suggestions on how I can do this?

Ali

+4
source share
3 answers

You can use select () in sys.stdin in conjunction with a timeout. Roughly speaking, your main loop will look like this (untested):

while True: r,w,e = select.select([sys.stdin], [], [], 600) if sys.stdin in r: # data available on sys.stdin if sys.stdin.read() == 'q': break # do gmail stuff 

To be able to read one character from stdin, you will need to put stdin in unbuffered mode. An alternative is described here . If you want everything to be simple, just ask the user to press Enter after "q"

The -u flag I mentioned earlier will not work: it can put pyton in unbuffered mode, but not your terminal.

Alternatively, ncursus may help. I'm just hinting, I don't have much experience with this; if I want a fantastic user interface, I would use TkInter.

+3
source

Ok try this python code ... (Tested on Linux. Most likely, you will not work on Windows - thanks to entering Aaron on it)

Received (copied and modified) from http://code.activestate.com/recipes/572182-how-to-implement-kbhit-on-linux/


 import sys, termios, atexit from select import select delay = 1 # in seconds - change this for your needs # save the terminal settings fd = sys.stdin.fileno() new_term = termios.tcgetattr(fd) old_term = termios.tcgetattr(fd) # new terminal setting unbuffered new_term[3] = (new_term[3] & ~termios.ICANON & ~termios.ECHO) # switch to normal terminal def set_normal_term(): termios.tcsetattr(fd, termios.TCSAFLUSH, old_term) # switch to unbuffered terminal def set_curses_term(): termios.tcsetattr(fd, termios.TCSAFLUSH, new_term) def getch(): return sys.stdin.read(1) def kbhit(): dr,dw,de = select([sys.stdin], [], [], delay) return dr <> [] def check_mail(): print 'Checking mail' if __name__ == '__main__': atexit.register(set_normal_term) set_curses_term() while 1: if kbhit(): ch = getch() break check_mail() print 'done' 
+1
source

If you really wanted (and wanted to spend a lot of resources), you could shorten the cycle to 200 ms pieces. So, sleep 200 ms, check input, repeat for up to five minutes, and then check your inbox. I would not recommend it.

While he sleeps, the process is blocked and will not accept input until the dream ends.

Oh, as an added note, if you press a key during sleep, it still has to go into the buffer, so it will be pulled out when the end of sleep and finally be read, IIRC.

0
source

All Articles