【问题标题】:Can't get python subprocess stdin to work on linux无法让 python 子进程标准输入在 linux 上工作
【发布时间】:2013-08-17 02:05:15
【问题描述】:

假设我在当前位置有一个目录调用 h33/,我想删除它。在 shell 中,我输入rm -ri h33,它就会消失。在python中我写道:

import subprocess
proc = subprocess.Popen(['rm','-ri','h33'],
    stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.communicate('yes')

如果目录中没有任何文件,这很好用!因此,如果我运行相同的 linux 命令,我必须回答是进入文件夹,是删除我在那里的单个文件,然后是删除目录。于是我写了:

import subprocess
proc = subprocess.Popen(['rm','-ri','h33'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for i in range(3):
    proc.communicate('yes')

...它不起作用!不知道为什么。

rm: descend into directory ‘hr33’? rm: remove regular empty file ‘hr33/blank’? rm: remove directory ‘hr33’? Traceback (most recent call last):
  File "multiDel.py", line 6, in <module>
    proc.communicate("yes")
  File "/usr/lib/python2.7/subprocess.py", line 806, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.7/subprocess.py", line 1377, in _communicate
    self.stdin.flush()
ValueError: I/O operation on closed file

我想做的主要事情是能够使用 subprocess 容纳多个输入(我希望这是有道理的)。请帮帮我

【问题讨论】:

  • shutil.rmtree() 有什么问题?
  • 那你为什么还要使用-i 开关呢?只需删除该选项,必要时添加-f,您将不会被询问
  • 但最重要的是,为什么不改用shutil.rmtree() 呢? Python 已经拥有您需要的工具!
  • 最后但同样重要的是,您可能正在寻找pexpect 来处理与子进程的“交互式”通信。
  • 我觉得有误会。 rm 命令只是一个例子。我真正想做的是用 python 处理交互式通信。明天我会研究一下pexpect

标签: python subprocess stdin popen


【解决方案1】:

.communicate() 关闭管道并等待子进程退出,因此您最多可以调用一次。假设rm 只是一些接受输入的交互式程序的示例(否则,请按照 cmets 中的建议使用 shutil.rmtree()rm -rf):

from subprocess import Popen, PIPE

proc = Popen(['rm','-ri','h33'], stdin=PIPE)
proc.communicate(b'yes\n' * 3)

或者你可以直接写信给proc.stdin

from subprocess import Popen, PIPE

proc = Popen(['rm','-ri','h33'], stdin=PIPE)
for i in range(3):
    proc.stdin.write(b'yes\n')
    proc.stdin.flush()
proc.communicate() # close pipes, wait for exit

通常您可能需要pty, pexpect modules 与子进程交互:

import pexpect # $ pip install pexpect

pexpect.run("rm -ri h33", events={r"'\?": "yes\n"}, timeout=30)

假设每个需要yes 答案的提示都以'? 结尾。

【讨论】:

    【解决方案2】:

    为什么不强制删除目录而不回答任何问题:

    import subprocess
    proc = subprocess.Popen(['rm','-rf','h33'],
        stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    

    【讨论】:

      猜你喜欢
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2012-03-13
      • 2018-12-14
      • 2012-07-18
      • 1970-01-01
      相关资源
      最近更新 更多