25

这是对这个问题的跟进,但如果我想将参数传递给stdinto subprocess,我怎样才能实时获得输出?这是我目前拥有的;我也尝试从模块中替换Popen,这只会导致脚本挂起。callsubprocess

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

附录:这适用于转移,但我只在最后看到输出,我想在转移发生时查看转移的详细信息。

4

3 回答 3

37

为了实时从子进程中获取标准输出,您需要准确地确定您想要什么行为;具体来说,您需要决定是要逐行处理输出还是逐字符处理,以及是要在等待输出时阻塞还是在等待时能够做其他事情。

看起来它可能足以让您的情况以行缓冲方式读取输出,阻塞直到每个完整的行进入,这意味着提供的便利功能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()

如果您需要写入进程的标准输入,只需使用另一个管道:

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()

加快另一个答案,无需通过文件间接将输入传递给子进程。

于 2013-07-01T20:25:42.457 回答
3

我想是这样的

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()

使用迭代器基本上会返回实时结果..

为了将输入发送到标准输入,您需要类似的东西

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)

这将类似于 linux shell 命令

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

请参阅 alps 答案以更好地传递给标准输入

于 2013-07-01T19:21:30.120 回答
2

如果您在开始读取输出之前传递所有输入,并且如果“实时”是指每当子进程刷新其标准输出缓冲区时:

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()
于 2014-03-04T14:46:24.347 回答