9 ms·
And this is why it is important to write something like set -eu on top of your bash scripts -- execution will stop on errors (non-zero retvals) and on und
by lpsz 12y ago
And this is why it is important to write something like
set -eu
on top of your bash scripts -- execution will stop on errors (non-zero retvals) and on undefined variables.
- guardian5x 12y agoI wonder why set -eu is not the default setting.
- anh79 12y agoset -u is good. set -e requires to change a lot of code. See for example https://github.com/icy/bash-coding-style#set--e https://github.com/icy/bash-coding-style#set--e
- blueskin_ 12y ago1. open bash 2. set -e 3. type an invalid command or run one that returns non-zero 4. "crap, where did my shell go?"
- twic 12y agoIt could be the default for non-interactive shells without causing this problem. Or we could have a more nuanced rule, where -e means "stop executing the current sequence of commands as soon as there is an error", where a "sequence of commands" is a single line in an interactive shell (so "false; whoami" would print nothing), or the entire file in a script. The real answer is that this has not been the default in the time between shells being invented and this comment being posted, and so the squillions of lines of shell script out there in the wild keeping the world turning have not been written with this in mind. Making it the default now would break a lot of things. With the benefit of hindsight, though, i would say that yes, this should have been the default in scripts. Oh well.
- jamiesonbecker 12y agoThere are lots and lots of these 'nuanced rules'. http://mywiki.wooledge.org/BashFAQ/105 http://mywiki.wooledge.org/BashFAQ/105
- darklajid 12y agoThat's not as simple or clear as you make it sound though. http://mywiki.wooledge.org/BashFAQ/105 http://mywiki.wooledge.org/BashFAQ/105 disagrees and refers to GreyCat's preference not to use -e at the bottom of the list of 'complications'.
- un1xl0ser 12y agoFrom the same page:"rking's personal recommendation is to go ahead and use set -e, but beware of possible gotchas. It has useful semantics, so to exclude it from the toolbox is to give into FUD." You can use set -e, and turn it off (set +e) for code blocks and things that are problematic. He could also add '|| true', and you may be able to use colon to avoid point problems without turning everything off. These are edge cases and you can easily work around them if you an advanced user. If you are not an advanced user then you should certainly use -e.
- un1xl0ser 12y ago$ diff -u /tmp/a /tmp/b --- /tmp/a 2015-03-24 08:33:00.021919797 -0400 +++ /tmp/b 2015-03-24 08:33:05.629963015 -0400 @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -e i=0 -let i++ +let i++ || true echo "i is $i" $ /tmp/a $ /tmp/b i is 1 $
- jiffytick 12y agoor check the variable before using it, like any other programming language: [[ "$VAR" ]] && rm -rf "$VAR/*" I think most of these issues stem from the fact that most developers that write shell scripts don't actually understand what they're doing, treating the script as a necessary annoyance rather than a component of the software.
- woah 12y agoElephant in the room- shell is a bizarre language
- Someone1234 12y agoYeah, everyone always loves to shit on BAT (which is fair, it is terrible) and VBS (which is slightly less fair) but inspite of how many problems Bash has (least of all the massive security issue last year), it gets off almost scot free. These bugs are indicative of Bash's design problems. Why is it used for init scripts? And don't even get me started on how Bash interprets filenames as part of the arguments list when using * (e.g. file named "-rf"). Say what you will about Powershell, but having a typed language that can throw a null exception is useful for bugs like these. The filename isn't relevant, and a null name on a delete won't try to clear out of the OS (just throw).
- sjolsen 12y ago>And don't even get me started on how Bash interprets filenames as part of the arguments list when using * (e.g. file named "-rf") That's not Bash. That's just... programs in Unix. Such is life when everything is stringly typed.
- rodgerd 12y ago> it gets off almost scot free. Not just scot free - during the Great systemd War of 2014 is was a talking point for the antis that using anything other than the pure, reliable simplicity of shell for service management was MADNESS!
- cellularmitosis 12y agoI also include set -o pipefail (exit if ANY command in a pipeline fails). Had to get bitten and waste an hour before that became a habit. set -e and set -o pipefail really should have been the default, rather than an opt-in.
- nwalfield 12y agoset -o pipefail makes common idioms a pain. Consider using head, which simply exits after it has read a few lines. In this case, the input process gets a SIGPIPE and exits with a non-zero exit code: Consider /tmp/test.sh: set -o pipefail yes foo | head $ bash /tmp/test.sh >/dev/null $ echo $? 141
- pixelbeat 12y agoThat's a bug IMHO which I reported at http://lists.gnu.org/archive/html/bug-bash/2015-02/msg00052.html http://lists.gnu.org/archive/html/bug-bash/2015-02/msg00052.... I've collated other mishandling of closed pipes at: http://www.pixelbeat.org/programming/sigpipe_handling.html http://www.pixelbeat.org/programming/sigpipe_handling.html
- quotemstr 12y agoFor a while now, I've thought we should change SIGPIPE's SIG_DFL action to _exit(0).