(no title)
twooster | 4 years ago
For example:
set -e
var="$( false )"
if [ $? -eq 0 ] ; then
echo Ok: "$var"
else
echo Not ok: $?
fi
If you run this program, neither "Ok" or "Not ok" will be echoed, because the program will exit with an error on the `var=` line. (Not to mention the $? on the not-ok line won't work because it will be the exit code of the `[` test command in the conditional, not the exit code of the captured subshell command).Instead the following will work:
set -e
if var="$( false )" ; then
echo Ok: "$var"
else
echo Not ok: $?
fi
Note that this will _not_ work: if ! var="$( false )"; then
echo Not ok: $?
fi
Your output will be "Not ok: 0". This is because negation impacts the exit code of the previous command.
chubot|4 years ago
This is a variant of the issue that the sibling comment brought up -- error handling is disabled inside "if" conditions.
In Oil the whole construct is unconditionally disabled by strict_errexit. It's too subtle.
Oil has 2 ways of capturing the exit code, including
and I'm looking for feedback to make sure that Oil has indeed fixed all of this stuff: https://www.oilshell.org/blog/2020/10/osh-features.htmlBasically the situation is "damned if you do and damned if you don't" in Bourne shell, so you need language/interpreter changes to really fix it. The rules are too tricky to remember even for shell experts -- there are persistent arguments on POSIX behavior that is over 20 years old, simply because it's so confusing.
https://github.com/oilshell/oil/wiki/Where-To-Send-Feedback
xyzzy_plugh|4 years ago
I don't know, I find it easier to not use set -e. I find it significantly easier to just explicitly handle all my errors. Having my script exit at some arbitrary point is almost never desirable.
I find chaining && and || pretty intuitive.
This is pretty contrived. I'd probably put the error handling in a function and then only handle the failure scenario: I never run into problems, this always works as expected, I don't need any language or interpreter changes to fix it. Once you realize `if` is just syntactic sugar and [ is just `test` then the world gets pretty simple.jaytaylor|4 years ago
Thanks for your work on Oil shell, I don't yet use it regularly but hope it becomes mainstream. I'm definitely rooting for you, chubot!
andsens|4 years ago
jbrot|4 years ago
Even worse, you can add the line “set -e” inside the function explicitly re-enabling it and it still won’t change the outcome because errexit wasn’t technically unset!
matvore|4 years ago
One such corner case is in pipelines. Only the last command in a pipeline can cause the script to terminate.
Another corner case is `foo && bar`, often used as an abbreviated `if`, will not exit when `foo` fails.
It is not a significant task to just add `|| exit $?` after any command whose failure should cause an abort.
mgerdts|4 years ago
set -euo pipefail
This addresses the pipeline case you mention and also notices use of unitialized variables.
unknown|4 years ago
[deleted]
Dr_Emann|4 years ago
rc=0 long command || rc = $? if (( rc == 0 ))...