3

次の Python コードがあります。

import sys
import traceback
fifo_in = sys.argv[1] 
while 1: 
  try:
    exec open(fifo_in)
  except:
    traceback.print_exc()
  sys.stdout.flush()

最初の引数は、 によって作成された名前付きパイプですmkfifo。したがって、次の出力は「1」です。

mkfifo input
python script.py input

... in a separate terminal ...

echo "print 1" > input

よかった、ここまではよかった。しかし、次のようなことをするecho "foobar" > inputと、スクリプトはトレースバックの一部しか出力しません。その後、別のコマンドを送信するまで一時停止し、出力がすべて混乱します。

echo "asdf" > input # pause here and check output
echo "print 1" > input

... in output terminal ...

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    exec open(fifo_in)
  File "in", line 1, in <module>
 ...PAUSES HERE...
    print 1
NameError: name 'asdf' is not defined

どうしたの?stdout を完全にフラッシュするにはどうすればよいですか? 代わりに使用しtraceback.format_excてから手で印刷してみましたが、同じ結果が得られます。呼び出しsys.stderr.flushても何も修正されません。また、ループにスリープを入れて、それが役立つかどうかを確認しましたが、何もしませんでした。

アップデート

私が見ている興味深い動作の 1 つ: もしそうならctrl+c、通常、プログラムは実行を続けます - try/except はちょうどキャッチし、KeyboardInterruptループし続けます。ただし、ctr+cエラーを送信した後にプログラムを終了すると、次のようになります。の中で一時停止するようですprint_exc

^CTraceback (most recent call last):
  File "test.py", line 10, in <module>
    traceback.print_exc()
  File "/usr/lib/python2.7/traceback.py", line 232, in print_exc
    print_exception(etype, value, tb, limit, file)
  File "/usr/lib/python2.7/traceback.py", line 125, in print_exception
    print_tb(tb, limit, file)
  File "/usr/lib/python2.7/traceback.py", line 69, in print_tb
    line = linecache.getline(filename, lineno, f.f_globals)
  File "/usr/lib/python2.7/linecache.py", line 14, in getline
    lines = getlines(filename, module_globals)
  File "/usr/lib/python2.7/linecache.py", line 40, in getlines
    return updatecache(filename, module_globals)
  File "/usr/lib/python2.7/linecache.py", line 132, in updatecache
    with open(fullname, 'rU') as fp:
KeyboardInterrupt
4

1 に答える 1

3

stdlibコードモジュールを見たいと思います

この動作は、execを使用した場合によるものです。ExecはPythonコードを評価するためのものであるため、「print 1」はPythonコードを実行しますprint 1が、「asdf」はコンテキストに存在しないためNameErrorを発生させます。exec open(fifo_in)動作しないはずなので奇妙です。その間も100%CPUを消費します。

更新:スリープ期間の修正これは、試してみるコードの修正バージョンです。

import sys
import time
import traceback
fifo_in = sys.argv[1]
try:
    fp = open(fifo_in) # will block until pipe is opened for write
except IOError:
    traceback.print_exc()
except OSError:
    traceback.print_exc()

data = None
while True:
    try:
        data = fp.read()
        try:
            exec data
        except:
            traceback.print_exc()
        finally:
            time.sleep(0.1)
    except KeyboardInterrupt:
        break
于 2013-02-11T21:30:10.523 に答える