使用子进程popen运行list命令字符串并获取输出

时间:2018-05-26 17:33:01

标签: python python-3.x unix subprocess popen

我正在尝试在像这样的

这样的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

3 个答案:

答案 0 :(得分:2)

创建新进程时,不要传递要运行的命令列表;相反,你传递一个单个命令 - 作为一个字符串(shell=True)或args列表(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()更简单 - 但任何一种方法都可行,具体取决于您对该过程的处理方式。

答案 1 :(得分:1)

你的问题是'睡眠3'会导致你从追踪中获得的错误,当我删除它有效时。

答案 2 :(得分:1)

为这些运行全部:

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)

第二个问题:这会捕获写入stdout的所有输出。要同时捕获stderr,也将其重定向到subprocess.PIPE