Bash – Why does the script suddenly exit after a command?

bash, exitstatus, shell, wget

I am trying to generate docsets for Dash following these instructions: http://kapeli.com/docsets.
The problem is, that the script doesn't continue after the wget and doesn't appear to throw any errors. Everything works fine when I copy the script into the Terminal.

I'm using MacOS 10.8.4 and the default bash.

#!/usr/bin/env bashset -emkdir -p $1.docset/Contents/Resources/Documents/echo "THIS RUNS"wget -rkp -l3 -np -nH --cut-dirs=1 --directory-prefix="./"$1".docset/Contents/Resources/Documents/" $2echo "THIS DOES NOT RUN"sed "s/NAME/$1/g" template > $1.docset/Contents/Info.plisttouch $1.docset/Contents/Resources/docSet.dsidx# (script continues) 

I looked at other posts like My shell script stops after exec but I'm not using exec here.

Why does the script exit?

Best Solution

You enabled set -e aka errexit.

Your script will exit if one of the commands returns a non-zero exit code, and it may not always be obvious which command specifically fails:

  • Some may print a helpful error identifying itself and the problem
  • Some (like wget) may briefly mention an error way back in pagefuls of output
  • Some (like grep) may not show errors or any output at all, the script just exits

To know which command is causing a problem, run script with -x aka xtrace:

bash -x script.sh

Or add set -x to the script itself:

set -xset -e...

This will cause the script to print out each command being executed, so you can see which one was the last.

If you would like to ignore the exit status of a command, you can add || true:

# Causes exit if you lack read permission on any directoryfind . -name '*.sh' # Does not cause the script to exitfind . -name '*.sh' || true

If you would like to be alerted when set -e would trigger in your script, you can set a trap:

#!/bin/bashset -e# Show error if commands exit with non-zerotrap 'ret=$?; echo "$0:$LINENO: Error: set -e triggered"; exit $ret' ERR# Would have failed silentlygrep doesnotexist /etc/passwdecho "This does not run"

When executed:

$ ./foo./foo:6: Error: set -e triggered