How to exit out of the shell script successfully so that python subprocess think it is successfull exit?

8,591

The problem is probably the set -e:

Exit immediately if a pipeline (which may consist of a single simple command), a subshell command enclosed in parentheses, or one of the commands executed as part of a command list enclosed by braces (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test following the if or elif reserved words, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command's return value is being inverted with !.

Thus almost every command can make the script exit with a non-zero exit code.

A special problem you are maybe not aware of: The let COUNT-=1 has exit code 1 if the result is 0. I.e. if the script has not executed exit 0 before then it must fail.

You can solve this problem e.g. with:

let COUNT-=1 || true

But the main question is, of course: What is the set -e doing there? And who uses that without understanding the consequences...

Share:
8,591

Related videos on Youtube

arsenal
Author by

arsenal

profile for ferhan on Stack Exchange, a network of free, community-driven Q&A sites http://stackexchange.com/users/flair/335839.png

Updated on September 18, 2022

Comments

  • arsenal
    arsenal over 1 year

    Below is my shell script which simply execute a url like this http://example.com:8080/beat and parse the response and verify certain conditions on it. If that condition is met, then exit successfully out of the shell script using exit 0.

    #!/bin/bash
    set -e
    
    COUNT=60 
    SUM_SYNCS=0
    SUM_SYNCS_BEHIND=0
    HOSTNAME=$hostname  
    
    echo $HOSTNAME
    
    while [[ $COUNT -ge "0" ]]; do
    
    #send the request, put response in variable
    DATA=$(wget -O - -q -t 1 http://$HOSTNAME:8080/beat)
    
    #grep $DATA for syncs and syncs_behind
    SYNCS=$(echo $DATA | grep -oE 'num_syncs: [0-9]+' | awk '{print $2}')
    SYNCS_BEHIND=$(echo $DATA | grep -oE 'num_syncs_behind: [0-9]+' | awk '{print $2}')
    
    echo $SYNCS
    echo $SYNCS_BEHIND
    
    #verify conditionals
    if [[ $SYNCS -gt "8" && $SYNCS_BEHIND -eq "0" ]]; then exit 0; fi
    
    #decrement the counter
    let COUNT-=1
    
    #wait another 10 seconds
    sleep 10
    
    done
    

    I am able to execute the above shell script from Python subprocess module successfully as shown below -

    proc = subprocess.Popen(shell_script, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/bash') 
    (stdout, stderr) = proc.communicate()
    if proc.returncode != 0:
        # log an error here
    else:
        # success log here
    

    But what is happening here is - If you see my shell script I am exiting out of the shell script using exit 0 which is a successful exit I guess and somehow in my Python code, it is logging an error after executing that shell script? Meaning it is going inside if statement somehow.

    So is there any way, I can replace exit 0 with some other successful exit call in shell script so that Python script can identify that, it's a successfull exit?

    I don't want to modify Python script code..

    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' about 10 years
      exit 0 is a successful exit. If the Python code says otherwise then either your script isn't returning with exit 0 after all, or there's a bug in a part of the Python script you didn't show. Add set -x to your script to make it log what it's doing, maybe some command is failing before exit 0 is hit. If you want further help, post complete code that we can run on our machine.
    • arsenal
      arsenal about 10 years
      let me try adding set -x in my shell script and then run it again. I have provided the full shell script code and python code which I provided is the only code which is making a call to shell script.. Only the url I haven't provided full and it will not work outside my company firewall so that is the reason I didn't provided.
    • Ketan Maheshwari
      Ketan Maheshwari about 10 years
      Can you show what is the value of proc.returncode. It is possible for instance that the return code is 127 if the python code can't find location of your shell script.
    • Gilles 'SO- stop being evil'
      Gilles 'SO- stop being evil' about 10 years
      It's part of your job when writing the question to provide runnable code if you want debugging help… For example, including the import directives in the Python fragment.
  • Ketan Maheshwari
    Ketan Maheshwari about 10 years
    I think OP edited the question and added set -e. It wasn't in the original script OP posted IIRC.
  • Hauke Laging
    Hauke Laging about 10 years
    @Ketan That would be really evil. But I don't see the hint (and link to the revision list) when it has been edited. AFAIK this happens only if you edit a few seconds / (very few) minutes after posting.
  • Ketan Maheshwari
    Ketan Maheshwari about 10 years
    my bad, I had it scrolled down and did not see/paste the top two lines while trying to reproduce.
  • Hauke Laging
    Hauke Laging about 10 years
    @Ketan No problem, I accept your upvote...