【问题标题】:Read stdout from subprocess until there is nothing left从子进程读取标准输出,直到没有任何剩余
【发布时间】:2015-10-20 22:18:53
【问题描述】:

我想在同一个 shell 中运行多个命令。经过一些研究,我发现我可以使用来自Popen 的返回过程保持外壳打开。然后我可以读写stdinstdout。我尝试这样实现它:

process = Popen(['/bin/sh'], stdin=PIPE, stdout=PIPE)
process.stdin.write('ls -al\n')
out = ' '
while not out == '':
    out = process.stdout.readline().rstrip('\n')
    print out

我的解决方案不仅丑陋,而且不起作用。 out 永远不会是空的,因为它交给了readline()。当没有内容可读时,如何成功结束while 循环?

【问题讨论】:

标签: python subprocess stdout popen readline


【解决方案1】:

使用iter实时读取数据:

for line in iter(process.stdout.readline,""):
   print line

如果您只想写入标准输入并获取输出,您可以使用通信来结束进程:

process = Popen(['/bin/sh'], stdin=PIPE, stdout=PIPE)
out,err =process.communicate('ls -al\n')

或者直接获取输出使用check_output:

from subprocess import check_output

out = check_output(["ls", "-al"])

【讨论】:

  • @AnandSKumar,是的,确实使用了 OP。
  • 但是如果我使用检查输出那么它不会保持相同的外壳不是吗? IE:如果其中一个命令正在更改当前目录,那么下次我调用check_output 时,它仍然会在开始目录中。
  • 你真正想做什么?
  • 我想在同一个 shell 中运行一长串命令。其中一些命令将使用cd 更改当前工作目录,运行一些命令,更改目录,再运行一些等等。因此,这些命令在同一个 shell 中运行对于工作目录是至关重要的设置正确。
  • 好的,你需要解析输出才能知道要写什么到stdin吗?
【解决方案2】:

您在子进程中运行的命令是sh,因此您正在读取的输出是sh 的输出。由于您没有向 shell 指示它应该退出,所以它仍然存在,因此它的标准输出仍然是打开的。

您也许可以将exit 写入其stdin 以使其退出,但请注意,无论如何,您都可以从其stdout 中读取不需要的内容,例如提示。

归根结底,这种方法一开始就有缺陷......

【讨论】:

  • 我还能如何处理这个问题?我想保留相同的 shell 的原因是因为我将运行的一些命令将更改工作目录。这就是为什么我想在同一个“shell”进程中运行它们以保持所有亲属路径正确。
  • @Juicy,一种选择是将所有命令放在一个 shell 脚本中并直接运行它,而不是一个接一个地将命令提供给sh。另一种是像你一样一个接一个地喂它们,但在最后添加exit。解析后者的输出可能会很棘手。您可能希望将 $PROMPT 设置为空。
猜你喜欢
  • 2018-02-25
  • 1970-01-01
  • 1970-01-01
  • 2016-03-14
  • 2011-02-17
  • 2015-01-20
  • 1970-01-01
相关资源
最近更新 更多