Running a list command strings with subprocess popen and getting the output

I'm trying to run multiple UNIX commands in a python script like this

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)

However my output does not contain all output and doesn't seem to run all the commands. Setting shell=False also causes an error.

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

Upvotes: 3

Views: 4424

Answers (3)

zvone
zvone

Reputation: 19352

To run all for these:

cmds = ['sleep 3', 'uptime','time ls -l /']

You have to call popen for each of them:

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()

Or simpler:

for cmd in cmds:
    output = subprocess.check_output(cmd, stdout=subprocess.PIPE, shell=True)

Second question: This captures all output written to stdout. To capture also stderr, redirect that into subprocess.PIPE as well.

Upvotes: 1

Paula Thomas
Paula Thomas

Reputation: 1190

Your problem is 'sleep 3' causes the error you get from the traceback, when I removed that it worked.

Upvotes: 1

FMc
FMc

Reputation: 42421

When you create a new process, you don't pass it a list of commands to run; rather, you pass it a single command -- either as a string (with shell=True) or as a list of args (with 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)

If you just want to collect stdout, subprocess.check_output() might be simpler than Popen() -- but either approach will work, depending on what you need to do with the process.

Upvotes: 3

Related Questions