However, if you are running bash, "help set" is fine.
FWIW, I really don't like pipefail as a default (e.g. piping to "head" causes random pipefails) and -e also has some confusing semantics. Also either failglob or nullglob are more important than either and -C is useful for some scripts as well.
[edit]
Simple example of confusing "set -e" semantics:
The following does not print "hi" and shows returns error status, as expected:
(set -e; echo hi); echo $?
But put it in an if statement, and it's suddenly success, and does print hi: if (set -e; false; echo hi); then echo hello; fi
The same problem applies to functions. The below function will remove all files in the current directory if it's called from a conditional, but not otherwise! foo() {
set -e
cd /some_directory # set -e means we exit if this fails
rm -rf *
}
I think just defining a die() function and using it after any command that must succeed is more verbose, but less error prone: cd /some_directory || die "chdir failed"
rm -rf * > (set -e; echo hi); echo $?
It works in my shell. :-/ It looks like you forgot to insert `false` command.You are pointing to the problem with -e not working in subshell/deep functions, because of POSIX. Right? It's described in bash documentation: http://www.gnu.org/software/bash/manual/html_node/The-Set-Bu...
> I think just defining a die() function and using it after any command that must succeed is more verbose, but less error prone:
Yep. It's the style I developed 12 years ago, when working at Bazaarvoice, when I was lead of devops team. I created the whole library for bash, to use this pattern consistently. See https://github.com/vlisivka/bash-modules#error-handling
https://gist.github.com/zachriggle/8574964d2e3078cdfae84b574...
e.g.
An error occurred on ./test:18
Frame 1 (./test:21)
18 false
19 }
20
21 >>> a
Frame 2 (./test:6)
3 source TRAPERR.zsh
4
5 a() {
6 >>> b
7 }
8
9 b() {
Frame 3 (./test:10)
7 }
8
9 b() {
10 >>> c
11 }
12
13 c() {
Frame 4 (./test:14)
11 }
12
13 c() {
14 >>> d
15 }
16
17 d() {
Frame 5 (./test:18)
15 }
16
17 d() {
18 >>> false
19 }
20
21 a #!/bin/bash
. import.sh strict log
a() {
b
}
b() {
c
}
c() {
d
}
d() {
false
}
a
Result: $ ./test.sh
[test.sh] PANIC: Uncaught error.
at d(./test.sh:13)
at c(./test.sh:10)
at b(./test.sh:7)
at a(./test.sh:4)
at main(./test.sh:16)
However, it stops to work at some point, e.g. in `for` loop, or in a subshell. zsh is better in this regard.