Live data from Hacker News

Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

mywiki.wooledge.org

61–70 of 114 posts

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#61
I am using zsh but only because it comes with a little more out the box and because zle's excellent vi mode (supports text objects for the win)

But I am wondering, does zsh fare better when it comes to writing more correct scripts or is it plagued with the same issues ?

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#62
post #28

Earlier quoted context omitted.

Yep as a programing language shell is weird, I am sure you know this better than me, but I got nerd sniped by your snippet, and want say what I think is happening. false the command returns 1, ! the command turns a 0 return code into a 1 and anything other than a zero into a 0, if is vaguely backwards from most languages in that it deals in return codes a rc of 0 is true and anything else is false in the first case f…

Yeah. Basically instead of treating ! specially, Bash treats it like any other command that sets $? afterwards. And since it always succeeds, you always end up with $?=0 after it. I don't know what kind of shell scripts the designers of this write, but the number of times I've wanted or found it helpful for ! to modify $? is has been exactly zero. I am almost certain that >99% of people who write shell scripts do not…

> Yeah. Basically instead of treating ! specially, Bash treats it like any other command that sets $? afterwards. And since it always succeeds, you always end up with $?=0 after it.

I don't think that is true, consider:

  # if  false ; then  echo "true $?" ; else echo "false $?" ; fi
  false 1
  # if ! false ; then  echo "true $?" ; else echo "false $?" ; fi
  true 0
  # if ! ! false ; then  echo "true $?" ; else echo "false $?" ; fi
  false 1
Basically, $? evaluates to the full condition inside the "if" sentence.

One of the first things I learned when starting to use $? was to assign it to a variable asap if I needed to use it more than once.

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#63
post #24

Earlier quoted context omitted.

Did you look at the examples? The first examples has me completely puzzled. #!/usr/bin/env bash set -e i=0 let i++ echo "i is $i"

Would you find it less surprising if the let command behaved differently than most other commands, and didn't stop the program if it returned a non-zero exit code? Because, this example works exactly the way I would expect. The next one (using the double parentheses syntax) is more questionable, and I could see it going either way, and would either look it up in the manual, or put an `|| true` after it to be safe. Th…

Come again, why is `i++` obviously an error when `i` is zero?

I’d expect an arithmetic operation to fail if I, say, divide by 0. Not if I add 1 to zero!

And just because behavior is documented doesn’t mean it’s not surprising or complicated.

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#65
post #44

In the 2000s, I was running extensive sets of simulations and data reduction scripts for a scientific experiment, and I was heavy relying on scripts to run the programs, collect the results, and distribute them over several servers. At first I developed those scripts using bash, but I needed to do math and complex iterations over file names and different parameter files, and I continuously stumbled upon weird behavio…

> Nowadays I use Python for complex scripts, but it's not the same as a language with native support for redirection and pipes! While this is no doubt right, I think you could build a little abstraction that simplified piping syntax considerable. The subprocess module is not terribly convenient, although it has gotten less confusing over the years. Python does have operator overloading, so you could even make it fanc…

There are a lot og libs that do that, but few people use them because it's not native to the language.

This is an important point for scripting as nobody wants to setup a venv to run a simple script.

Zippapp are a solutions to that but most people don't know abot them. Also, it's not convenient enough to make at the moment.

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#66

Short answer: because it's Bash. No syntax or language construct will do what you expected.

I tend to think of Bash as a syntax-free language. There are no clear rules, you just have to kind of make it work every time. It's like the programming version of a freestyle rap or Parkour.

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#67
post #57

I use "set -Eeuo pipefail" in pretty much all bash scripts. (and often -x as well) Makes things much saner. This post is a better introduction than the submission: https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_p...

Thanks! I'm not doing a lot of bash scripting, so there's always something weird happening. `set -Eeuxo pipefail` will be my new default.

It's still not enough though.

https://www.oilshell.org/blog/2022/05/release-0.10.0.html

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#68
Because bash error handling is a thousand blades and no handle.

https://blog.habets.se/2021/06/The-uselessness-of-bash.html

I've reviewed a lot of code, bash and otherwise. I have never, not once, reviewed bash code that didn't have subtle bugs. And this is code written by smart people.

Re: Why doesn't Bash’s ‘set -e’ do what I expected? (2021)

#70

Shell scripts can be thought like C++. They can be sanely managed only if one adopts a strict subset of functionalities. The page is probably oriented at situations where one needs to support any version of bash and any obscure/inadvisable functionality (mind that there are still devs that mix sh and bash syntax in the same script), which is very inconvenient and error prone, so manual error handling may make sense.…

I disagree. Bash basically cannot be used correctly. It's like gets() in C; a knife with a blade but no handle. Unsafe at any speed.

https://blog.habets.se/2021/06/The-uselessness-of-bash.html

C++ can be used correctly. It's easier since C++11, with smart pointers and stuff. I'm not going to argue that writing solid C++ is easy, but it IS possible.

Bash basically can't be used correctly. Even a simple command pipeline of three commands, with actual error handling, is probably more code in bash than in any other language.

Post reply on HN