Spike
Spike

Reputation: 329

How to su and run python script in shell?

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?

Upvotes: 2

Views: 1168

Answers (2)

Anil_M
Anil_M

Reputation: 11463

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’

Upvotes: 1

Barmar
Barmar

Reputation: 781721

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.

Upvotes: 2

Related Questions