Waltz Waltz - 2 months ago 6x
Python Question

Python subprocess returncode takes on different values

I'm running a python script demo.py which is as follows:

#!/usr/bin/env python

from subprocess import Popen, PIPE, CalledProcessError

process = Popen(["/root/script.sh"], stdout = PIPE, stderr = PIPE)
process_out, process_err = process.communicate()
return_code = process.returncode
if process_out:
print "output:", process_out
if process_err:
print "error:", process_err
print "return code:", return_code
except CalledProcessError as e:
print "CalledProcessError:", e
except Exception, fault:
print "fault:", fault

script.sh is as follows:


cd /root/
mkdir foo
cd foo
cat << EOF > bar.txt
random text

The directory foo already exists. Hence, script.sh should fail and it does. demo.py correctly catches the error in process_err and prints it:

error: mkdir: cannot create directory `foo': File exists

But the value of return_code is still 0 (which indicates successful run).

If my script.sh is as follows:


cd /root/
mkdir foo

process_err prints the same error message but now the value of return_code is 1.

Where is the problem?

Please also suggest scenarios in which process.returncode takes on values other than 0 and 1.


This is not a problem with Python, but with your Bash script that is continuing execution after mkdir. This is how Bash works by default, you have to tell it to exit when it encounters an error.


set -e

Or, if you can't change the Bash script and you can only change the Python code:

process = Popen(['bash', '-e', '/root/script.sh'], stdout = PIPE, stderr = PIPE)

From help set:

-e Exit immediately if a command exits with a non-zero status.