5

I'm trying to understand how to access from a bash script the return value of a python script.

Clarifying through an example:

foo.py

def main():
    print ("exec main..")
    return "execution ok"

if __name__ == '__main__':
    main()

start.sh

script_output=$(python foo.py 2>&1)
echo $script_output

If I run the bash script, this prints the message "exec main..".

How can I store in script_output the return value (execution ok)? If I direct execution ok to stdout, the script_output will capture all the stdout (so the 2 print statement).

Is there any way to implement this?

Thanks! Alessio

1
  • 1
    I think a more natural solution is for the python script to write to a file, which will then be read by the bash script. Commented Jan 16, 2018 at 11:15

3 Answers 3

5

Add a proper exit code from your script using the sys.exit() module. Usually commands return 0 on successful completion of a script.

import sys

def main():
    print ("exec main..")
    sys.exit(0)

and capture it in shell script with a simple conditional. Though the exit code is 0 by default and need not be passed explicitly, using sys.exit() gives control to return non-zero codes on error cases wherever applicable to understand some inconsistencies with the script.

if python foo.py 2>&1 >/dev/null; then
    echo 'script ran fine'
fi
Sign up to request clarification or add additional context in comments.

6 Comments

Is sys.exit(0) necessary? You can automatically get the exit status through $?, if you want to notify user that this script ran successfully manually then only we use sys.exit(code)
@AvinashRaj: Yes the documentation says it is optional. But I think if you have control over the script it is safe to send the code to ensure it
hey @Inian your solution looks more elegant than write something to stderr and grab the output of it from bash. It is close enough to what I was looking for! thanks!
@AvinashRaj: sys.exit([error code]) is necessary since the python script could end on error internally but the python process will return zero anyway. That way you can force the error signaling to other processes.
can you explain what your command is doing? especially the dev null part? python foo.py 2>&1 >/dev/null?
|
5

You can get the previous command's output status through $?. If the python script ran successfully without any stderr, it should return 0 as exit code else it would return 1 or any number other than 0.

#!/bin/bash
python foo.py 2>&1 /dev/null
script_output=$?
echo $script_output

1 Comment

can you explain what your command is doing? especially the dev null part? python foo.py 2>&1 >/dev/null?
3

Bash contains only return code in $?, so you can't use it to print the text from python's return. My solution is write in to the stderr in python script, next print only stderr in bash:

import sys
    
    
def main():
    print ("exec main..")
    sys.stderr.write('execution ok\n')
    return "execution ok"
    
if __name__ == '__main__':
    main()

Bash:

#!/bin/bash
    
script_output=$(python foo.py 1>/dev/null)
echo $script_output

Output:

execution ok

3 Comments

I wanted to avoid to write anything to stderr here, I'm sorry if I have not specified in my question.
@AlessioG well, I think Inian's solution is the best for you.
can you explain what your command is doing? especially the dev null part? python foo.py 2>&1 >/dev/null?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.