3
#Example Script
wget http://file1.com
cd /dir
wget http://file2.com
wget http://file3.com

I want to execute the bash script line by line and test the exit code ($?) of each execution and determine whether to proceed or not:

It basically means I need to add the following script below every line in the original script:

if test $? -eq 0 
then
    echo "No error"
else
   echo "ERROR"
   exit
fi

and the original script becomes:

#Example Script
wget http://file1.com
if test $? -eq 0 
then
    echo "No error"
else
   echo "ERROR"
   exit
fi
cd /dir
if test $? -eq 0 
then
    echo "No error"
else
   echo "ERROR"
   exit
fi
wget http://file2.com
if test $? -eq 0 
then
    echo "No error"
else
   echo "ERROR"
   exit
fi
wget http://file3.com
if test $? -eq 0 
then
    echo "No error"
else
   echo "ERROR"
   exit
fi

But the script becomes bloated.

Is there a better method?

J.Joe
  • 644
  • 2
  • 7
  • 20
  • http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_02_03.html – James Jithin Sep 07 '16 at 08:45
  • This is not quite the same as the 'flagged duplicate' - But because of it I can't add my own (properly formatted) answer! – anthony Jan 19 '17 at 00:28
  • I am actually surprised no one came up with a 'trap DEBUG' solution. You can use $? to get the wget exit value, $BASH_COMMAND to check that it is a wget, and $BASH_LINENO to tell you which wget. – anthony Jan 19 '17 at 00:29

5 Answers5

2

set -e makes the script fail on non-zero exit status of any command. set +e removes the setting.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • If I use this method, how can I know which line (in the original script) causes the error? I want to print that line. – J.Joe Sep 07 '16 at 09:02
  • @J.Joe , You can use `set -x` to achieve that. So `set -ex` should do. – aleksanderzak Sep 07 '16 at 09:10
  • @choroba Actually, I think a better method will be `2>&1 | tee -a log` so you can check the log anytime you want. – J.Joe Sep 07 '16 at 09:18
  • 1
    @J.Joe also have a look at http://stackoverflow.com/questions/10743026/how-to-display-last-command-that-failed-when-using-bash-set-e. – aleksanderzak Sep 07 '16 at 09:23
2

There are many ways to do that.

For example can use set in order to automatically stop on "bad" rc; simply by putting

set -e 

on top of your script. Alternatively, you could write a "check_rc" function; see here for some starting points.

Or, you start with this:

check_error () {
  if [ $RET == 0 ]; then
    echo "DONE"
    echo ""
  else
    echo "ERROR"
    exit 1
  fi
}

To be used with:

echo "some example command"
RET=$? ; check_error

As said; many ways to do this.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • If I use this method, how can I know which line (in the original script) causes the error? I want to print that line. – J.Joe Sep 07 '16 at 08:57
2

One can use set -e but it's not without it's own pitfalls. Alternative one can bail out on errors:

command || exit 1

And an your if-statement can be written less verbose:

if command; then

The above is the same as:

command
if test "$?" -eq 0; then
Andreas Louv
  • 46,145
  • 13
  • 104
  • 123
  • Upvoted. Though maybe emphasize even more that explicitly examining `$?` is almost never necessary, and that control statements such as `if` and `while` already do this, and that's their very purpose. – tripleee Sep 07 '16 at 09:17
1

Best bet is to use set -e to terminate the script as soon as any non-zero return code is observed. Alternatively you can write a function to deal with error traps and call it after every command, this will reduce the if...else part and you can print any message before exiting.

trap errorsRead ERR;
function errorsRead() {

   echo "Some none-zero return code observed..";
   exit 1;
}


    somecommand #command of your need
    errorsRead  # calling trap handling function 
P....
  • 17,421
  • 2
  • 32
  • 52
0

You can do this contraption:

wget http://file1.com || exit 1

This will terminate the script with error code 1 if a command returns a non-zero (failed) result.

Nidhoegger
  • 4,973
  • 4
  • 36
  • 81