Reputation: 23
I have a script.command
file with a shell script inside, so that I can double click it to execute in a new terminal window. When it finishes the script it automatically closes regardless of the exit code. Back in the days I used to put ifs after every troublesome command like this:
iCanCouseError
if [[ $? -ne 0 ]]; then
read -p "Press enter to close"
exit 1
fi
This was keeping the terminal open until I press a button, so that I could read the logs and determine what caused an exception.
But now I switched to a much more convenient method: set -e
at the beginning of the file. It automatically exits the script with an error code if any command fails. But now I can't read logs before the terminal closes. I wonder if there is some way to set an exit function in addition to set -e
that will always execute right before script exits, so that I could put read
command there to stop terminal from closing in case of non-zero exit code.
Upvotes: 1
Views: 52
Reputation: 203502
Consider not using set -e
as it's a mess (see https://mywiki.wooledge.org/BashFAQ/105) and also consider setting a trap to do something different for success vs other exit statuses instead of putting code below your "real" code, something like:
sig_handler() {
exit_status=$?
echo "Doing signal-specific stuff"
exit "$exit_status"
}
trap sig_handler INT HUP TERM QUIT
iCanCouseError
Google for better alternative trap functions/usage, there are plenty of suggestions out there for you to choose from dependent on what you want to do.
Upvotes: 1
Reputation: 20450
Package up your commands in a separate "iCanCauseError" executable script file that starts with a shebang.
Then iCanCauseError || read -p "Press enter"
suffices.
A zero exit value will be interpreted as True, satifying the short-circuiting OR operator, so it doesn't have to evaluate that second disjunct. Notice that we have a separate Bash child running the commands, rather than say a (subshell) or function within current shell.
Also, when setting -e
, you might as well set this:
set -e -o pipeline
Imagine you do grep x y | sort | awk ... | wc -l
,
and the awk
script bombs out with non-zero exit status.
The effect of setting the pipeline option is to make that fatal,
similar to how set -e
makes non-zero status fatal for single command.
It's just less surprising.
And while you're at it, the unrelated set -u
may be of interest.
This will do variable interpolation: echo ${HOME}/
.
But imagine there's a typographic error, so we
accidentally get just a /
slash output: echo ${HOMS}/
.
The "unset variable" -u
setting will make that typo a fatal error.
Upvotes: 1