0

In bash how do we make the script to automatically exit if a command line return code is not zero. For example:

#!/bin/bash

cd /something_something
mv file_a /somedir/file_a # this produce an error
echo $?  # This produce a non-zero output
echo "We should not continue to this line"

I know we can debug bash script with #!/bin/bash -x but sometime the script is too long, it run so fast, and we missed important error.

And I don't want to keep writing [[ $? -ne 0 ]] && run next_command

RonPringadi
  • 1,294
  • 1
  • 19
  • 44
  • 3
    You can use `set -e` or `#!/bin/bash -e` – anubhava Nov 26 '18 at 18:35
  • ^^ + Otherwise known as the "Error Exit" flag – Zak Nov 26 '18 at 18:37
  • `mv file_a /somedir/file_a || exit`? – Cyrus Nov 26 '18 at 18:37
  • @anubhava thanks that's what I need. Strangely my `bash --help` doesn't show this option, regardless, it works. Could you please move it as an answer? – RonPringadi Nov 26 '18 at 18:39
  • Note [BashFAQ #105](http://mywiki.wooledge.org/BashFAQ/105#Exercises), describing why what you're asking for is a bad idea. It's impossible to tell the difference between "X returned a value of false" and "X failed", and lots of things return nonzero exit status for reasons that aren't actually failures. Worse, `set -e` has lots of heuristics to try to guess at those cases, they're [different between different shells (and releases of the same shell)](https://www.in-ulm.de/~mascheck/various/set-e/), and those differences lead to surprises/breakage. – Charles Duffy Nov 26 '18 at 18:39
  • For option `-e` take a look at `help set`. – Cyrus Nov 26 '18 at 18:39
  • BTW, `cd /something_something || exit` (or `|| return`, as appropriate for context) is a much better way to do explicit error handling, rather than `[[ $? -ne 0 ]] && ...`. Checking `$?` on a following line is bad practice for other reasons -- not only is it wordy, but it's easy to break your flow-control logic by adding logging or other changes that modify `$?` unintentionally. – Charles Duffy Nov 26 '18 at 18:47

1 Answers1

2

There are lots of problems with using set -e. Just join the commands with &&, and test the result with an if statement.

if cd /something_something && mv file_a /somedir/file_a; then
    echo $?
    exit
fi
echo "Both cd and mv worked"
chepner
  • 497,756
  • 71
  • 530
  • 681