how to read an incomplete line from a Python pty.fork() child output?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #!/usr/bin/python
import pty
import os
import sys
pid, out = pty.fork()
if pid:
try:
for line in os.fdopen(out):
sys.stdout.write(line)
except IOError:
pass
else:
sys.stdout.write("foobar")
sys.stdout.flush() |
没有打印。 如何让它打印出孩子发出的不完整线?
-
运行它为我打印foobar。也许在else块中添加sys.stdout.flush()?
-
@IsmailBadawi绝对不打印任何东西,只需双重检查。我运行Python 2.7。让我试试同花顺
-
@IsmailBadawi nope,即使有同花顺也不打印
-
难道你不应该在作家端关闭流吗? Python的输入例程(可能通过getline实现)可能知道它是否遇到不完整的行或者是否要写入更多的字符?
-
@MarkGaleck我在看到"foobar"时没有任何问题
-
@ 5gon12eder不能 - 问题是,我在使用它的情况下,当孩子可能会死,同时发出一条线
-
您是否从命令行运行此功能?如果是这样你在Linux,Windows或Mac上?
-
@BadKarma我看到两个人没有任何问题,我绝对没有看到它。这必须是Python版本,还是某些环境设置? ID10T我认为这次是不可能的,因为我为你粘贴了代码。我应该检查什么样的环境条件?
-
@BadKarma我在Linux上,Fedora的一个版本,在命令行上是的,我只是做。> / foobar.py
-
@ 5gon12eder你有一个观点。怎么会知道?我不知道。但是,对于BadKarma和Ismail来说,它确实以某种方式"知道"。也许我们问他们。
-
我也没有看到任何输出(GNU / Linux)。我将except IOError: pass更改为except IOError as e: print(e),它告诉我[Errno 5] Input/output error。
-
@ 5gon12eder哦,好吧,我本来期待的,在异常代码中,我将能够恢复不完整的行 - 在孩子死亡时调用异常代码,因此Python知道,没有更多的输出并且可以可能收集不完整的行。唉,我不知道是否可能,或者如果是,如何从异常处理程序中执行此操作。
-
是的,所以我和5gon12eder看到它是一种方式,完全一样。而BadKarma和Ismail,从另一个角度来看。那为什么会这样?
-
@MarkGaleck我能看到它的原因是因为我在我的Mac上运行它。我阅读了sys工具,它们高度依赖于平台,并不一定支持所有这些工具。我一直在做一些关于解决方案的研究,并且正在取得一些进展。如果我发现有效的话,我会发一个答案
-
@BadKarma哎呀,非常感谢你,我可以给你买午餐或东西:)?
-
@MarkGaleck找到此资源。也许试试看? stackoverflow.com/questions/10409897/…
以下是纯粹推测:对输入流进行迭代可能是在将字符读入缓冲区时实现的,直到遇到换行符或文件结束条件为止。 如果孩子死了,一些实现(依赖于平台)会从缓冲区中释放剩余的字符。
也许使用一些更低级别的I / O可以避免这个问题。 当我在我的GNU / Linux系统上运行原始脚本时,我没有得到"foobar"而是IOError。 但是,当我将其更改为
1 2
| with os.fdopen(out) as istr:
sys.stdout.write(istr.read()) |
它打印"foobar"而不会抛出任何异常。
更新:为了一次读取一个流,我们需要求助于更低级别的I / O. 我发现以下内容对我有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import pty
import os
import sys
pid, out = pty.fork()
if pid:
while True:
buffsz = 10 # Use a larger number in production code.
buff = b''
died = False
try:
buff = os.read(out, buffsz)
except IOError:
died = True
sys.stdout.write(buff.decode())
if len(buff) == 0 or died:
break
else:
with sys.stdout:
# Also try writing a longer string with newlines.
sys.stdout.write("foobar") |
不幸的是,这意味着我们需要手动重新组装缓冲区块并扫描换行符。 这很不方便,但肯定可以做到。
-
是的,但是......当然,它会立即读取整个可用输出。 如果输出是持续的和庞大的,我认为这是行不通的。 我试图在这里使用readline(),不像以前那样工作。
-
对不起我不想,但我不得不接受。 因为我想阅读不完整的一行。 实际上,它会立即读取整个内容,而不是逐行读取。
-
@MarkGaleck我对解决方案有所改进。 希望它现在对你更有用。