LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Bash Exit Status and Scripts (https://www.linuxquestions.org/questions/linux-software-2/bash-exit-status-and-scripts-760078/)

hawk__0 10-06-2009 11:02 AM

Bash Exit Status and Scripts
 
Not sure if this is the right forums for this... but...

is it possible to have an if statement cover an entire script, so I can check if at any point there is an exit status that isn't 0?

catkin 10-06-2009 11:24 AM

Quote:

Originally Posted by hawk__0 (Post 3709736)
Not sure if this is the right forums for this... but...

is it possible to have an if statement cover an entire script, so I can check if at any point there is an exit status that isn't 0?

Yes you can have a script that is nothing but an if statement but it will not test every command's exit status.

The question feels like you are asking for help with a solution that is probably not the best solution to the problem. How about you tell us what the problem is?

You may find LQ's How To Ask a Question helpful.

hawk__0 10-06-2009 11:29 AM

Well I am writing several backup scripts. 1 for each server. They are being rsync'd and I want to be able to execute a certain command if at any point to script fails. There are a few otehr things being run other than just the rsync command (archiving the data, making folders, etc)

lutusp 10-06-2009 11:35 AM

Quote:

Originally Posted by hawk__0 (Post 3709772)
Well I am writing several backup scripts. 1 for each server. They are being rsync'd and I want to be able to execute a certain command if at any point to script fails. There are a few otehr things being run other than just the rsync command (archiving the data, making folders, etc)

1. Make sure the exit conditions are clearly defined in the script -- don't leave anything to chance.

2. Specify the exit code you want, don't leave that to chance either:

Code:

$ (commmand) || exit (choose a number 0-255)
The above will exit on the failure of (command) with the code you specify.

3. Read the exit codes in the parent script:

Code:

$ (script_name)

$ echo $? (prints exit code of most recently executed command).


hawk__0 10-06-2009 11:41 AM

Okay thanks, let me make sure I understand this correctly. The way I've scripted this so far, it seems like this will integrate quite nicely...

I have 1 script that executes all scripts. It's something like this:

FINAL_SCRIPT:
script1.sh
script2.sh
script3.sh
etc etc etc

So, can I do this?

script1.sh || exit 1
if [ $? -eq 1 ]; then
echo "Oh noes!!"
fi
script2.sh..... etc

lutusp 10-06-2009 12:08 PM

Quote:

Originally Posted by hawk__0 (Post 3709784)
Okay thanks, let me make sure I understand this correctly. The way I've scripted this so far, it seems like this will integrate quite nicely...

I have 1 script that executes all scripts. It's something like this:

FINAL_SCRIPT:
script1.sh
script2.sh
script3.sh
etc etc etc

So, can I do this?

script1.sh || exit 1
if [ $? -eq 1 ]; then
echo "Oh noes!!"
fi
script2.sh..... etc

No, that would always produce the wrong exit code -- the one you provided. The desired exit code should be created by the script itself.

From your example it looks like you want to stop the sequence on the first error. If so, do it this way:

script1.sh && script2.sh && script3.sh (etc..)

hawk__0 10-06-2009 12:20 PM

No, I don't want to stop it, I just want to stop the specific script itself. Each script is backing up a different server and each script appends a line of text to a file (which says if the backup succeeded or not) and then the main script emails the report after backing everything up.

Edit: It's just a pain editing 5 scripts and after each of the 4+ commands adding an if statement to it.

lutusp 10-06-2009 12:52 PM

Quote:

Originally Posted by hawk__0 (Post 3709818)
No, I don't want to stop it, I just want to stop the specific script itself. Each script is backing up a different server and each script appends a line of text to a file (which says if the backup succeeded or not) and then the main script emails the report after backing everything up.

Edit: It's just a pain editing 5 scripts and after each of the 4+ commands adding an if statement to it.

Quote:

No, I don't want to stop it, I just want to stop the specific script itself.
But the exit status can only be read after the script exits, in which case it has already stopped. Which means I really don't understand what you want.

Do you want to make a report about success or failure after the script exits? Is this the goal? Then:

$ script-name && echo "success!" >> destination_log

Add things like date and time and the name of the script to the "echo" quoted text.

The bottom line is that to program a computer, you have to be very, very specific. It turns out the same thing is true here.

hawk__0 10-06-2009 12:58 PM

Thanks, you have the right idea now and that should do now that I think of it...

H_TeXMeX_H 10-06-2009 01:33 PM

What you usually have to do is for each command that you run in the script, check the exit status. You cannot do it like you say and somehow put a big if statement, it would always return true. So check each command, either put each in an if statement or just use the or || notation.

catkin 10-06-2009 02:07 PM

If you want to keep your master script short you could run the sub-scripts in a loop
Code:

for script in script1.sh script2.h ...
do
    $script
    rc=$?
    if [[ $rc -ne 0 ]];then
        <error logging code as required, including reporting the script's actual exit code>
    fi
done


chrism01 10-06-2009 07:41 PM

Extending the above; each script1.sh etc probably has multiple cmds, any of which can fail
Code:

# empty log file for this run
>master_log.log

for script in script1.sh script2.sh ...
do
    # Concatenate any output/errors into log file;
    # just tracking the exit code doesn't tell us what went wrong
    $script >>master_log.log 2>&1
    rc=$?
    if [[ $rc -ne 0 ]];then
        <error logging code as required, including reporting the script's actual exit code>
    fi
done



All times are GMT -5. The time now is 08:31 AM.