从需要stdin的子进程实时打印stdout

2024-09-28 23:15:56 发布

您现在位置:Python中文网/ 问答频道 /正文

这是this question的后续操作,但是如果我想将参数传递给stdinsubprocess,如何实时获取输出?这就是我目前所拥有的;我还尝试用subprocess模块中的call替换Popen,这只会导致脚本挂起。

from subprocess import Popen, PIPE, STDOUT
cmd = 'rsync --rsh=ssh -rv --files-from=- thisdir/ servername:folder/'
p = Popen(cmd.split(), stdout=PIPE, stdin=PIPE, stderr=STDOUT)
subfolders = '\n'.join(['subfolder1','subfolder2'])
output = p.communicate(input=subfolders)[0]
print output

在前一个问题中,我不需要通过stdin我被建议使用p.stdout.readline,那里没有空间将任何东西传送到stdin

附录:这对传输有效,但我只在最后看到输出,我想在传输过程中看到传输的细节。


Tags: 模块from脚本cmdoutputstdinstdoutcall
3条回答

如果在开始读取输出之前传递了所有输入,如果是“实时”,则表示子进程刷新其stdout缓冲区时:

from subprocess import Popen, PIPE, STDOUT

cmd = 'rsync --rsh=ssh -rv --files-from=- thisdir/ servername:folder/'
p = Popen(cmd.split(), stdout=PIPE, stdin=PIPE, stderr=STDOUT, bufsize=1)
subfolders = '\n'.join(['subfolder1','subfolder2'])
p.stdin.write(subfolders)
p.stdin.close() # eof
for line in iter(p.stdout.readline, ''):
    print line, # do something with the output here
p.stdout.close()
rc = p.wait()

我想是这样的

from subprocess import Popen, PIPE, STDOUT

p = Popen('c:/python26/python printingTest.py', stdout = PIPE, 
        stderr = PIPE)
for line in iter(p.stdout.readline, ''):
    print line
p.stdout.close()

使用迭代器将基本上返回实时结果。。

为了向stdin发送输入,您需要

other_input = "some extra input stuff"
with open("to_input.txt","w") as f:
   f.write(other_input)
p = Popen('c:/python26/python printingTest.py < some_input_redirection_thing', 
         stdin = open("to_input.txt"),
         stdout = PIPE, 
         stderr = PIPE)

这类似于

%prompt%> some_file.o < cat to_input.txt

请参阅阿尔卑斯山答案,以便更好地传递到标准输入

为了实时地从子流程中获取stdout,您需要准确地决定您想要什么行为;具体地说,您需要决定是逐行处理输出还是逐字处理输出,以及您是希望在等待输出时阻塞还是能够在等待时执行其他操作。

看起来,以行缓冲方式读取输出可能就足够了,阻塞直到每个完整的行进入,这意味着subprocess提供的便利函数足够好:

p = subprocess.Popen(some_cmd, stdout=subprocess.PIPE)
# Grab stdout line by line as it becomes available.  This will loop until 
# p terminates.
while p.poll() is None:
    l = p.stdout.readline() # This blocks until it receives a newline.
    print l
# When the subprocess terminates there might be unconsumed output 
# that still needs to be processed.
print p.stdout.read()

如果需要写入进程的stdin,只需使用另一个管道:

p = subprocess.Popen(some_cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# Send input to p.
p.stdin.write("some input\n")
p.stdin.flush()
# Now start grabbing output.
while p.poll() is None:
    l = p.stdout.readline()
    print l
print p.stdout.read()

另一个答案是,不需要通过文件间接地将输入传递给子流程。

相关问题 更多 >