store return value of a Python script in a bash script

PythonBashReturnReturn Value

Python Problem Overview


I want to execute a python script from a bash script, and I want to store the output of the python script in a variable.

In my python script, I print some stuff to screen and at the end I return a string with:

sys.exit(myString) 

In my bash script, I did the following:

outputString=`python myPythonScript arg1 arg2 arg3 `

But then when I check the value of outputString with echo $outputString I get everything that the Python script had printed to screen, but not the return value myString!

How should I do this?

EDIT: I need the string because that tells me where a file created by the Python script is located. I want to do something like:

fileLocation=`python myPythonScript1 arg1 arg2 arg1`
python myPythonScript2 $fileLocation

Python Solutions


Solution 1 - Python

sys.exit(myString) doesn't mean "return this string". If you pass a string to sys.exit, sys.exit will consider that string to be an error message, and it will write that string to stderr. The closest concept to a return value for an entire program is its exit status, which must be an integer.

If you want to capture output written to stderr, you can do something like

python yourscript 2> return_file

You could do something like that in your bash script

output=$((your command here) 2> &1)

This is not guaranteed to capture only the value passed to sys.exit, though. Anything else written to stderr will also be captured, which might include logging output or stack traces.

example:

test.py

print "something"
exit('ohoh') 

t.sh

va=$(python test.py 2>&1)                                                                                                                    
mkdir $va

bash t.sh

edit

Not sure why but in that case, I would write a main script and two other scripts... Mixing python and bash is pointless unless you really need to.

import script1
import script2

if __name__ == '__main__':
    filename = script1.run(sys.args)
    script2.run(filename)

Solution 2 - Python

sys.exit() should return an integer, not a string:

sys.exit(1)

The value 1 is in $?.

$ cat e.py
import sys
sys.exit(1)
$ python e.py
$ echo $?
1

Edit:

If you want to write to stderr, use sys.stderr.

Solution 3 - Python

Do not use sys.exit like this. When called with a string argument, the exit code of your process will be 1, signaling an error condition. The string is printed to standard error to indicate what the error might be. sys.exit is not to be used to provide a "return value" for your script.

Instead, you should simply print the "return value" to standard output using a print statement, then call sys.exit(0), and capture the output in the shell.

Solution 4 - Python

read it in the docs. If you return anything but an int or None it will be printed to stderr.

To get just stderr while discarding stdout do:

output=$(python foo.py 2>&1 >/dev/null)

Solution 5 - Python

In addition to what Tichodroma said, you might end up using this syntax:

outputString=$(python myPythonScript arg1 arg2 arg3)

Solution 6 - Python

Python documentation for sys.exit([arg])says:

> The optional argument arg can be an integer giving the exit status (defaulting to zero), or another type of object. If it is an integer, zero is considered “successful termination” and any nonzero value is considered “abnormal termination” by shells and the like. Most systems require it to be in the range 0-127, and produce undefined results otherwise.

Moreover to retrieve the return value of the last executed program you could use the $? bash predefined variable.

Anyway if you put a string as arg in sys.exit() it should be printed at the end of your program output in a separate line, so that you can retrieve it just with a little bit of parsing. As an example consider this:

outputString=`python myPythonScript arg1 arg2 arg3 | tail -0`

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRicky RobinsonView Question on Stackoverflow
Solution 1 - PythonLoïc Faure-LacroixView Answer on Stackoverflow
Solution 2 - Pythonuser647772View Answer on Stackoverflow
Solution 3 - PythonchepnerView Answer on Stackoverflow
Solution 4 - PythontzellekeView Answer on Stackoverflow
Solution 5 - PythonAlpView Answer on Stackoverflow
Solution 6 - PythonGiovaView Answer on Stackoverflow