se84
se84

Reputation: 43

Automatic exit from bash shell script on error: set +e does not seem to do the job

While I knew for 20 years that shell scripts do not care about errors I keep being amused about this carelessness by default. And even when you explicitly require them not to swallow error and to follow crash early principle that still does not happen.

Referring to Automatic exit from bash shell script on error, set +e does not seem to do the job, here is a short example:

#!/bin/bash -vx
set +e
apt-get install nonexisting1
apt-get install nonexisting2
set -e

Output:

#!/bin/bash -vx
set +e
+ set +e
apt-get install nonexisting1
+ apt-get install nonexisting1
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package nonexisting1  <--- first error, now stop!
apt-get install nonexisting2           <--- why do we continue here?
+ apt-get install nonexisting2
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package nonexisting2
set -e
+ set -e

How do I make sure that my script either does all the commands without error or stops immediately? I do not like to write || exit 1 at the end of almost every line.

Upvotes: 4

Views: 1427

Answers (5)

Ricky Levi
Ricky Levi

Reputation: 8007

The set -e works - but not on if statements take a look at this example:

#!/bin/bash -xv

set -e
+ set -e

if ["$DIR" == "somedirectory"]; then
    echo "directory match"
fi
+ '[' == 'somedirectory]'
./test.sh: line 5: [: missing `]'          <= error

echo "bla 1"
+ echo 'bla 1'
bla 1
echo "bla 2"
+ echo 'bla 2'
bla 2

See that line: 5 has a syntax issue the [] should have spaces between them:

# this
if ["$DIR" == "somedirectory"]; then

# should be
if [ "$DIR" == "somedirectory" ]; then

Even that set -e exists the bash script continue ... for some reason

Explanation: http://mywiki.wooledge.org/BashFAQ/105

Upvotes: 0

codeforester
codeforester

Reputation: 43089

For a four-line script like yours, set -e does feel reasonable, assuming apt-get does exit with a non-zero exit code for errors.

However, lots of discussions regarding set -e on SO indicate that it is not a reliable technique for error handling. The Bash documentation confirms it.

We have no option but to check the status variable $? after each command if we want our script to be reliable.

Upvotes: 0

rghome
rghome

Reputation: 8841

Options in shell are (counter-intuitively) switched on using a minus and switched off using a plus.

Even so, the set -e option will only work if the program correctly returns non-zero error statuses.

Although the apt-get manual says it should do this, other posts indicate that it frequently does not (see apt-get update exit status).

Verify the return status of your apt command after it runs (e.g. using echo $?). If it returns non-zero, set -e should work.

Upvotes: 6

NeverGoodEnough
NeverGoodEnough

Reputation: 352

I guess you are simply using set +e in place of set -e and vice versa. If you simply do

#!/bin/bash -vx
set -e
apt-get install nonexisting1
apt-get install nonexisting2
set +e

it should stop after the first line.

Upvotes: 6

mah454
mah454

Reputation: 1930

Why you set "+e" first of script ?
this is my example :

#!/bin/bash  -xv

set -e 

dskakj

echo "Hello dear" 
apt-get install bash

output :

#!/bin/bash  -xv

set -e 
+ set -e

dskakj
+ dskakj
./a.sh: line 5: dskakj: command not found

Note : not need set "+e" end of script .

Upvotes: 1

Related Questions