python - 异常后标准输出不会刷新

标签 python stdout

我有以下 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 也没有解决任何问题。我也试过在循环中 sleep 以查看是否有帮助,但没有任何帮助。

更新

我看到一个有趣的行为:如果我 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

最佳答案

我想你想看看the stdlib code module

此行为来自使用 exec。 Exec 用于评估 python 代码,因此“print 1”执行 python 代码 print 1,其中“asdf”将引发 NameError,因为它在上下文中不存在。 exec open(fifo_in) 很奇怪,因为它不应该工作。同时也会占用 100% 的 CPU。

更新:修复 sleep 持续时间 这是要尝试的代码的修改版本。

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

关于python - 异常后标准输出不会刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14819675/

相关文章:

python - 加入图像后找到新的坐标

c++ - 漂亮地将解析树打印到标准输出?

python - 在 Django 中使用抽象多重继承时外键冲突

python - Django 从数据库生成模型

c++ - 对 stdout 的默认缓冲区大小感到困惑

python - 记录器配置以记录到文件并打印到标准输出

python - Cronjob - 如何输出 stdout 并忽略 stderr

linux -/dev/tty 和 stdin/stdout/stderr 是什么关系?

python - all() 与具有中断性能的 for 循环

python - 无法从网页获取连接到不同参展商的链接