Chris F
Chris F

Reputation: 16673

In Python 2 or 3, how to get both the return code and return string of system call?

I know I can do this to get the execute a system command, e.g., make, and it'll give me either a 0 for success, or a non-zero for a failure.

import os
result = os.system('make')

I also know I can do this so I can see the return string of the command

import commands
result = commands.getoutput('make')

How can I accomplish both, where I get both the return code and the return string result, so then I can

if return_code > 0:
  print(return_string)

Thanks.

Upvotes: 4

Views: 1462

Answers (2)

Kos
Kos

Reputation: 72241

The canonical way to run stuff with Python is to use the subprocess module, but it has a good bunch of functions enigmatically called check_call or check_output and these functions tend to have cryptic warnings like "Do not use stdout=PIPE or stderr=PIPE with this function", so let me provide some more:

Step 1: Run the script

proc = subprocess.Popen(["your_command", "parameter1", "paramter2"],
                        stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Now the process is running in the background and you have a reference to it.

EDIT: I almost forgot - if you'd like to retrieve the output later, you have to tell Python to create reading pipes for standard output. If you don't do this step, stdout and stderr will just go to your program's standard output and standard error, and communicate won't pick them up in step 2.

Step 2: wait for the process to finish and get its output

stdout, sterr = proc.communicate()
return_code = proc.returncode

communicate allows you to do some more things too:

  • pass stdin data to the process (input= parameter)
  • give a time limit for the process to finish, to avoid hanging (timeout= parameter)

Make sure to also catch and properly handle any exceptions from Popen or communicate.


If you don't care about old Python, there's a simpler method called subprocess.run that Does It All:

completed_process = subprocess.run(
    ['your_command', 'parameter'],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)
# this starts the process, waits for it to finish, and gives you...
completed_process.returncode
completed_process.stdout
completed_process.stderr

For error-checking you can call completed_process.check_returncode() or just pass check=True as an additional argument to run.

Upvotes: 4

kichik
kichik

Reputation: 34704

Another possibly simpler method is:

import subprocess
try:
 output = subprocess.check_output("make", stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
  print('return code =', e.returncode)
  print(e.output)

Upvotes: 0

Related Questions