2011-12-21 21 views
5

Unix less(1)を使って端末にテキストを表示するプログラムを書いています。関連部分は次のとおりです。less(1)のサブプロセスを終了した後に入力が失敗する

私はKeyboardInterrupt例外を待ち受けています。もし私が1つを捕まえると、私はSIGTERMシグナルで少しを殺し、私のプログラムを終了します。

これが起こると、私はシェルプロンプトに戻りますが、シェルはもはや私が書いていることをエコーし​​ませんし、再び動作させるためにはリセット(1)をしなければなりません。

どのように私は墓に私のstdinを取ることなく死ぬことを減らすためのアイデアですか?完全なソースがhttps://github.com/jforberg/rfc/blob/master/rfc.py

EDITで提供されています:いくつかの実験をした後、私はデフォルトでは(1)より少ないと男性(1)の両方を制御-Cストロークを無視することを見出しました。だから、単にそれを無視することは実行可能な選択肢かもしれません。私はそれがそれを行う適切な方法だと私は確信していないので、もし誰かが私はまだ非常に興味を持っている提案があります。

#!/usr/bin/env python 
from subprocess import PIPE, Popen 

p = Popen(['less'], stdin=PIPE) 
try: 
    p.communicate(''.join("%d\n" % i for i in range(1000))) 
except KeyboardInterrupt: 
    print("Press `q` to exit.") 
    p.wait() 
+0

安価な回避策として、スクリプトの最後に 'os.system( 'reset')'を置くことができます。適切な解決策は、おそらく控えめに「控えめ」に止めること、つまり、sigintを書き、それに「q」を書いて、それが完了するのを待つことです。 – wim

+0

@ウィムあなたの「適切な解決策」:もちろん!自分自身に「q」を書くという考えは私には起こりませんでした。 Linuxをプログラミングしていても、すべてがファイルであることを忘れないでください。それを答えに移してください。私はそれを受け入れます。 – jforberg

+2

'setpgid'トリックがないので、' less'はあなたのPythonプロセスと同じプロセスグループになければならないので、あなたのPythonプロセスと同じ^ Cを受け取ります。しかし、それは独自の特別な処理をしようとしていると思います... '-e'(' --quit-at-eof')を使用して、プログラムがハングアップした後に終了するのはどうですか? – ephemient

答えて

1

最も簡単な方法は、(qを押すことによって)適切にlessを終了するには、ユーザーを依頼することです

  1. 少なく、男性と関連プログラムにはありません制御Cで終了すると、彼らはその時点で何をしているのかを中止します。だから、単にキーストロークを無視することは選択肢のようです。これにより、長い検索などの長い操作をプログラムを終了させずに中止できる便利な機能が保持されます。同様のプログラム(この場合はUnix man)のようにプログラムが機能することも望ましいことです。

  2. lessでは、ほとんどの非対話型コマンドと同様に、Control-Cで終了する-Kオプションを受け入れます。

1

は基本的に2つのオプションがあります:

0

ああ! J.F. Sebastianの解は良いですが、すべてのケースでうまくいきません。私のアプリケーションでは、 "less + F -S logfilename"で "tail -f"のように "less"を使いたいと思っています。ユーザーは通常モードで入力するためにCTRL + Cキーを押し、終了するにはQキーを押す必要があります。この手順のために

は問題なく発生し、私は(J.F.セバスチャンコードに基づく)は、次の6行のソリューションを作ってみた:

logpath = os.path.join(cwd, "filename.log") 
less = Popen(["less","+F","-S", logpath]) 
retcode = None 
while retcode is None: 
    try: retcode = less.wait() 
    except KeyboardInterrupt: pass 

私は、これはオリジナルを解決だと思います。少ないものを入力するには、wait()またはcommunicate(input)のいずれかのPopenメソッドを調整する必要があります。

関連する問題