呼び出されたときに継続的に実行され、5 分ごとに Gmail の受信トレイをチェックするスクリプトがあります。5 分ごとに実行するには、time.sleep() 関数を使用しています。ただし、q を押すたびにユーザーにスクリプトを終了してもらいたいのですが、time.sleep() を使用している場合は実行できないようです。これを行う方法について何か提案はありますか?
アリ
呼び出されたときに継続的に実行され、5 分ごとに Gmail の受信トレイをチェックするスクリプトがあります。5 分ごとに実行するには、time.sleep() 関数を使用しています。ただし、q を押すたびにユーザーにスクリプトを終了してもらいたいのですが、time.sleep() を使用している場合は実行できないようです。これを行う方法について何か提案はありますか?
アリ
sys.stdin でselect()をタイムアウトと組み合わせて使用できます。大まかに言えば、メイン ループは次のようになります (未テスト)。
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
標準入力から 1 文字を読み取ることができるようにするには、標準入力を非バッファ モードにする必要があります。別の方法については、こちらで説明しています。物事をシンプルに保ちたい場合は、ユーザーに「q」の後にEnterキーを押すように要求するだけです
前述の -u フラグは機能しません。pyton を非バッファ モードにする可能性がありますが、端末はそうではありません。
あるいは、ncursus がここで役立つかもしれません。私はほのめかしているだけです。これについてはあまり経験がありません。派手なユーザー インターフェイスが必要な場合は、TkInter を使用します。
Ok。このpythonコードを試してください...(Linuxでテストされています。ほとんどの場合、Windowsでは動作しません-それに関するAaronの入力のおかげです)
これは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'
本当にやりたい (そして多くのリソースを浪費したい) 場合は、ループを 200 ミリ秒のチャンクに分割できます。200 ミリ秒スリープし、入力を確認し、5 分が経過するまで繰り返し、受信トレイを確認します。しかし、私はそれをお勧めしません。
ただし、スリープ中はプロセスがブロックされ、スリープが終了するまで入力を受け取りません。
ああ、追加のメモとして、スリープ中にキーを押すと、それはまだバッファに入る必要があるため、スリープが終了して入力が最終的に読み取られると、IIRC が引き出されます。