bash strict mode (set -e)? - not so fast unless you know these quirks
Quick question: * how regularly do you put `set` in your bash scripts? * how often do you trap signals in your bash scripts? On to the video:
The Problem with Bash 'Strict Mode'
- Why I Don’t Use `set -euo pipefail`
More bash enlightenment by Dave @ YSAP on the topic of bash strict mode (set -e). There are some damned weird gotchas to beware of! I had no idea. His "contrived" example of how it can make your life much harder: $ ((i=0)) ; echo "i: ${i} exit code: $?" i: 0 exit code: 1 Longer form: $ ((i=-1)) ; echo $? 0 $ ((i=0)) ; echo $? 1 $ ((i=1)) ; echo $? 0 So, it's returning an "error" code of 1 that will cause `set -e` to bring your program to a grinding halt where it is inappropriate to do so. No errors were generated in that code. His second example is even more inscrutable. I really have been questioning bash a lot lately. He then covers `set -o pipefail` and again, weird behaviour. $ ( cat /usr/share/dict/canadian-english-insane |head -n 1) A $ (set -o pipefail cat /usr/share/dict/canadian-english-insane |head -n 1) Here, the "error" was that the pipe closed because `head` got its one line and `cat` had no where to send the rest of the file. Finally, he covers `set -u` for unbound variables. It's nice. https://www.youtube.com/watch?v=4Jo3Ml53kvc The comments are also good, possibly the best on any tech channel i.e. how to handle exit values > 128. He shouts out the shellcheck.net service (accessed via CLI!)
From: Ron via Talk <talk@lists.gtalug.org>
Quick question:
* how regularly do you put `set` in your bash scripts?
As often as I remember to.
* how often do you trap signals in your bash scripts?
Only ones that I put in "production" use. It's often a sign to switch languages. Generally: to clean up resources when a failure happens.
On to the video:
The Problem with Bash 'Strict Mode'
- Why I Don’t Use `set -euo pipefail`
More bash enlightenment by Dave @ YSAP on the topic of bash strict mode (set -e).
There are some damned weird gotchas to beware of! I had no idea.
His "contrived" example of how it can make your life much harder:
$ ((i=0)) ; echo "i: ${i} exit code: $?" i: 0 exit code: 1
That's what ((expression)) is supposed to do. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. I don't use ((expression)). I don't doubt that it is sometimes convenient The idea of assignment being legal within an ((expression)) does violence to the original model of the Bourne Shell. As do the rules for double-quotes.
Longer form:
$ ((i=-1)) ; echo $? 0 $ ((i=0)) ; echo $? 1 $ ((i=1)) ; echo $? 0
Look at the part of the man page that I quoted above.
So, it's returning an "error" code of 1 that will cause `set -e` to bring your program to a grinding halt where it is inappropriate to do so. No errors were generated in that code.
What is the definition of "error" in bash? A non-zero return status from a command. So ((0)) is an error.
He then covers `set -o pipefail` and again, weird behaviour.
I don't use it. A case analysis is needed to know whether that signal is actually an error.
participants (2)
-
D. Hugh Redelmeier -
Ron