使用子进程 popen 运行列表命令字符串并获取输出
Posted
技术标签:
【中文标题】使用子进程 popen 运行列表命令字符串并获取输出【英文标题】:Running a list command strings with subprocess popen and getting the output 【发布时间】:2018-11-05 19:25:02 【问题描述】:我正在尝试在这样的 python 脚本中运行多个 UNIX 命令
import subprocess
cmds = ['sleep 3', 'uptime','time ls -l /']
p = subprocess.Popen(cmds,stdout=subprocess.PIPE,shell=True)
while p.poll() is None:
time.sleep(0.5)
tempdata = p.stdout.read()
print(tempdata)
但是我的输出不包含所有输出并且似乎没有运行所有命令。设置 shell=False 也会导致错误。
Traceback (most recent call last):
File "task1.py", line 32, in ?
p = subprocess.Popen(commands,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)
File "/usr/lib64/python36/subprocess.py", line 550, in __init__
errread, errwrite)
File "/usr/lib64/python36/subprocess.py", line 996, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
【问题讨论】:
【参考方案1】:当您创建一个新进程时,您不会向它传递要运行的命令列表;相反,您将单个命令传递给它——作为字符串(使用shell=True
)或作为参数列表(使用shell=False
)。
import subprocess
cmds = ['sleep 1', 'uptime', 'ls -l /']
for cmd in cmds:
stdout = subprocess.check_output(cmd, shell=True)
print('\n# '.format(cmd))
print(stdout)
如果您只是想收集标准输出,subprocess.check_output()
可能比Popen()
更简单——但任何一种方法都可以使用,具体取决于您需要对该过程执行的操作。
【讨论】:
【参考方案2】:您的问题是“睡眠 3”导致您从回溯中得到的错误,当我删除它时它起作用了。
【讨论】:
【参考方案3】:运行所有这些:
cmds = ['sleep 3', 'uptime','time ls -l /']
您必须为每个人调用 popen:
for cmd in cmds:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
while p.poll() is None:
time.sleep(0.5)
output = p.stdout.read()
或者更简单:
for cmd in cmds:
output = subprocess.check_output(cmd, stdout=subprocess.PIPE, shell=True)
第二个问题:这会捕获所有写入标准输出的输出。要同时捕获 stderr,请将其重定向到 subprocess.PIPE
。
【讨论】:
以上是关于使用子进程 popen 运行列表命令字符串并获取输出的主要内容,如果未能解决你的问题,请参考以下文章
subprocess.Popen,从子进程(子)中获取变量[重复]