6 ms·
TiL: The shell does not exit if the command that fails is a part of any command executed in a && or || list except the command following the final && or ||. Re
by mfrw 3y ago
TiL: The shell does not exit if the command that fails is a part of any command executed in a && or || list except the command following the final && or ||.
Reference: https://www.gnu.org/software/bash/manual/bash.html#index-set https://www.gnu.org/software/bash/manual/bash.html#index-set
- jks 3y agoThis is because && and || are often used as conditionals: [ -e README ] && cat README avoids an error if the file README doesn't exist, and [ -e README ] || echo "You should write a README!" works the opposite way. What's more pernicious is that pipelines don't cause the shell to exit (assuming set -e) unless the last command fails: grep foo README | sort does not fail if README doesn't exist, unless you've also used `set -o pipefail`.
- strangesmells02 3y agoso what happens?? it just hang up on the foo??
- osmsucks 3y ago`grep` should terminate with an empty output on `stdout` and an error message on `stderr`, then `sort` will successfully sort the empty contents of `stdout`
- bityard 3y ago"Fails" is a higher-level concept than the shell is concerned with. Failure conditions and reactions are entirely at the discretion of the programmer and are not built as an assumption into the shell. The only thing /bin/false does is return 1. Is that a failure? No, that's how it was designed to work and literally what it is for. I have written hundreds of shell scripts and lots of them contain commands which quite normally return non-zero in order to do their job of checking a string for a certain pattern or whatever. Programs are free to return whatever exit codes they want in any circumstance they want, and common convention is to return 0 upon success and non-zero upon failure. But the only thing that the shell is concerned with is that 0 evaluates to "true" and non-zero evaluates to "false" in the language. It would be pretty inconvenient if the shell exited any time any program returned non-zero, otherwise if statements and loops would be impossible. If a script should care about the return code of a particular program it runs, then it should check explicitly and do something about it. As you linked to, there are options you can set to make the shell exit if any command within it returns non-zero, and lots of beginner to intermediate shell script writers will _dogmatically_ insist that they be used for every script. But I have found these to be somewhat hacky and full of weird hard-to-handle edge cases in non-trivial scripts. My opinion is that if you find yourself needing those options in every script you write, maybe you should be writing Makefiles instead.
- deleted 3y ago[deleted]
- rightbyte 3y ago> It would be pretty inconvenient if the shell exited any time any program returned non-zero, otherwise if statements and loops would be impossible. In another life I worked as a Jenkins basher and if I remember correctly I had this problem all the time with some Groovy dsl aborting on any non zero shell command exit. It was so annoying.
- jstimpfle 3y agoThere are more arcane things to learn about shell, at some point one has to go shrug, it's a fine tool for getting quick results but not for writing robust programs.
- arendtio 3y agoIn my opinion, it is one of the biggest flaws in the shell language design, because it means, that a function can lead to different results independent of the arguments, but depending of the context from which you call it. And it even overrides explicitly setting `set -e` within a function. Some time ago I gave an example: https://news.ycombinator.com/item?id=22213830 https://news.ycombinator.com/item?id=22213830