实时从需要标准输入的子进程中打印标准输出。
实时从需要标准输入的子进程中打印标准输出。
这是对这个问题的补充,但如果我想将参数传递给stdin
,我怎样才能实时获取输出?这是我目前的代码;我也尝试用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
。
补充说明:这对于传输是有效的,但我只能在结束时看到输出,我想在传输过程中看到传输的详细信息。
问题的出现原因是,当使用subprocess模块创建子进程并与其交互时,如果在开始读取输出之前将所有输入传递给子进程,并且通过“实时”指的是每当子进程刷新其标准输出缓冲区时,可能会出现无法实时打印子进程的标准输出的情况。
解决方法是在创建子进程时,设置stdout参数为PIPE以捕获子进程的标准输出,并且设置stdin参数为PIPE以向子进程发送输入。然后,使用p.stdin.write()方法将输入传递给子进程,最后使用p.stdin.close()方法发送文件结束符号。接下来,使用iter(p.stdout.readline, '')循环遍历子进程的标准输出,同时使用print语句打印输出内容。最后,关闭子进程的标准输出并使用p.wait()方法等待子进程结束。
实时从需要stdin的子进程中打印stdout的问题的出现的原因是我们需要决定我们想要的确切行为,即我们需要决定是按行还是按字符处理输出,以及在等待输出时是否阻塞,还是能够在等待期间执行其他操作。对于我们的情况,按行缓冲读取输出并阻塞直到每一行完全到达可能足够满足需求,这意味着subprocess提供的便利函数已经足够好用。
解决方法是使用subprocess模块提供的方便函数来读取子进程的输出,并且如果需要向子进程的stdin写入内容,可以使用另一个管道。
使用subprocess.PIPE作为stdout参数可以实现按行缓冲读取输出的效果,并且可以在等待输出时阻塞,直到每一行完全到达。如果需要向子进程的stdin写入内容,可以使用subprocess.PIPE作为stdin参数,并使用stdin.write()方法写入内容。
需要注意的是,如果子进程生成大量的stderr输出,使用stderr=PIPE参数可能会导致代码死锁。此外,在写入完输入后,需要调用p.stdin.close()或flush()方法来确保子进程能够看到输入。
如果使用readline()方法读取输出,并使用print()打印输出,可能会导致额外的空白字符。可以使用sys.stdout.write()方法来替代print()方法以避免这个问题。
另外,如果想同时读取stdout和stderr输出,可以使用select模块来实现。但需要注意的是,p.stdout.readline()方法是阻塞的,所以需要在读取输出时采用非阻塞的方式。
问题出现的原因是需要从子进程的标准输出(stdout)实时打印输出内容,同时需要向子进程的标准输入(stdin)传递输入内容。解决方法是使用subprocess模块中的Popen类,并通过设置stdin和stdout参数来实现。
具体的解决方法如下所示:
from subprocess import Popen, PIPE, STDOUT # 创建子进程,并指定stdout为PIPE 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) # 创建子进程,并指定stdin为打开的文件 p = Popen('c:/python26/python printingTest.py < some_input_redirection_thing', stdin=open("to_input.txt"), stdout=PIPE, stderr=PIPE) # 更好的传递输入内容请参考alps的答案
以上代码中,通过使用迭代器实时读取子进程的标准输出,并通过设置stdin参数将输入内容传递给子进程。需要注意的是,需要将输入内容写入到文件中,并将打开的文件作为stdin参数传递给子进程的构造函数。
以上就是解决从子进程的标准输出实时打印内容,并向子进程的标准输入传递内容的方法。