2

What I want to do is let my shell script stop when my python script, which is run by shell, exit unnormally. However I have to su to the ossadm to run the python script, how can I get the correct exit code when I su

Here is my code:

# shell script
    su ossadm <<EOF
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python ${SRC_DIR}/main.pyc
    echo $?
    if [[ $? = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi
EOF

# main.py
def main():
    sys.exit(1) # for testing

then run the script, it always prints "0" and "suceess", or change the sequence:

    su ossadm <<EOF
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python ${SRC_DIR}/main.pyc
EOF
    echo $?
    if [[ $? = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi

# main.py
def main():
    sys.exit(1) # for testing

This one will give me weirder "1" and "success".

Could this kind of processing could be done in shell script?

3
  • For last example, echo $? succeeds, so on the next line $? is 0. Commented Sep 25, 2018 at 15:45
  • Why are you running main.pyc directly? The speedup (especially in this case) is negligible, and it won't reflect any changes you may make to main.py without explicitly recompiling it. Commented Sep 25, 2018 at 16:07
  • @chepner to be honest, it's because my company want me to do so..to keep users from reaching the source code SO directly, althrough we all know it doesn't help Commented Sep 26, 2018 at 1:47

2 Answers 2

2

You need to quote the EOF token. Otherwise, variables in the here-doc are expanded by the original shell, so $? contains the exit status of the last command you ran before su.

# shell script
su ossadm <<'EOF'
    . /opt/oss/manager/bin/engr_profile.sh # which only can be executed by ossadm
    python "${SRC_DIR}"/main.pyc
    status=$?
    echo $status
    if [[ $status = 0 ]]; then
        echo "success"
    else
        echo "failure: $?"
    fi
EOF

If SRC_DIR is a variable set in the original shell, make sure you export it so that it will be inherited by the shell run by su, since it will no longer be expanded by the original shell. But if it's set by engr_profile.sh, quoting the token will make it expand correctly.

The reason you're getting 1 and success in your second version is because the echo statement sets $? based on its own success. If you want to print an exit status and also test it, you need to save it in another variable, as I've done with the status variable above.

Sign up to request clarification or add additional context in comments.

2 Comments

It might be the intention to expand $SRC_DIR before running the script, though, so quoting EOF may not be the right answer.
Then it needs to be exported. I've added info about that.
1

Depending on you shell you can try something like this.

su ossadm -c '. /opt/oss/manager/bin/engr_profile.sh; 
python "${SRC_DIR}"/main.pyc'  && echo "sucess" || echo "failure"

Here -c flag will run commands as ossadm.

Where && is logical and which runs code block after it if previous command is successful . || is logical or and code block after this runs if previous command fails.

To make matter more clear, you can put code for success and failure in different files

su ossadm -c '. /opt/oss/manager/bin/engr_profile.sh;
python "${SRC_DIR}"/main.pyc' && /tmp/b.sh || /tmp/c.sh

Where b.sh runs when su command (in your case python script) exits with code ‘0’ And. c.sh runs when su command (in your case python script) exits with code ‘1’

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.