Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to act on an error code and collect stdout at the same time?

I have this python3 program. It sets error code 0 when it works and non-zero when it fails. It puts the good message into stdout and the failure string into stderr. I think it’s well-behaved.

#! /bin/python3

import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

cs = sys.argv[1]

if str(cs) == "1":
    print("GOOD")
else:
    eprint("BAD")
    sys.exit(1)

See how I test it:

$ X=`python3 example.py 1`; echo It is: $X
It is: GOOD
$ X=`python3 example.py 0`; echo It is: $X
BAD
It is:

I have this bash program that calls the python program:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#! /bin/bash

function do_example() {
    local DB=$1
    local URI=`python3 example.py $DB`
    RESULT=$?
    if [ $RESULT -eq 0 ]; then
        echo $URI
        echo success
    else
        echo $URI
        echo failed
    fi
}

do_example 1
do_example 0

It runs a python program first. Captures the stdout. Then it checks the return value. It doesn’t work. It should say success and then failed. Instead, it says success both times. It doesn’t work. It doesn’t handle the error code correctly.

$ ./example.sh 
success
BAD
success
$ ./example.sh 
GOOD
success
BAD

The generalized question is how to collect the stdout into a local variable and act on the error code at the same time?

>Solution :

local‘s exit code overrides the one from the command substitution. To work around this, always split apart local declarations from assignments if the assignments could fail:

local URI
URI=`python3 example.py $DB`
RESULT=$?

By the way, you don’t need to save the exit code in a variable if you check it in the if statement. Also, it’s best to avoid uppercase variable names as they could clash with built-in names. Finally, I recommend using $(...) in place of backticks; it is easier to nest substitutions.

local db=$1

local uri
if uri=$(python3 example.py "$db"); then
    echo "$uri"
    echo success
else
    echo failed
fu
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading