Live data from Hacker News

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

mywiki.wooledge.org

21–30 of 114 posts

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

#21
post #15

Earlier quoted context omitted.

Curious on this one, do you have an example showing it not working as expected?

$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi $ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi msg

That's correct behavior though.

You should do

if ARG=false

Then use $ARG not $? in the if statement.

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

#22
post #21

Earlier quoted context omitted.

$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi $ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi msg

That's correct behavior though. You should do if ARG=false Then use $ARG not $? in the if statement.

It's the best kind of correct, yes.

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

#23

If you modify your PS1 to include $? It makes writing shell scripts that rely on exit codes a lot easier. It should be the default in my opinion. Build scripts that fail and return 0 are my nemesis.

> Build scripts that fail and return 0 are my nemesis.

I was also once party to an argument caused by a developer who thought that non-zero exit codes were an acceptable way to communicate success states. I suspect that he may have been trying to communicate different success conditions, but I couldn't tell you for certain.

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

#24

I'm not sure what this person did expect. That bash magically parsed the output and memory of running programs, and read the user's thoughts, to determine if the state of the program indicates a condition that the user would consider an error? set -e does exactly what you'd expect, arguably, with the exception of subshells and conditions. And those rules are extremely simple to learn too. If you understand when a sta…

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. The fact that it changed in a minor release is pretty bad though.

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

#25
post #21

Earlier quoted context omitted.

That's correct behavior though. You should do if ARG=false Then use $ARG not $? in the if statement.

It's the best kind of correct, yes.

It's a pretty bizarre use case, why would you need the second if statement, you already are in logic based on the return code

I can't think of an example of the if statement being confusing that isn't relying on $?

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

#27
post #25

Earlier quoted context omitted.

It's the best kind of correct, yes.

It's a pretty bizarre use case, why would you need the second if statement, you already are in logic based on the return code I can't think of an example of the if statement being confusing that isn't relying on $?

  error=0
  if ! some_command; then error=$?; bar; fi
  echo "blah"
  return $error

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

#28
post #15

Earlier quoted context omitted.

Curious on this one, do you have an example showing it not working as expected?

$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi $ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi msg

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 false has a rc of 1 this will execute the else list then the test command 1 is equal to 0(rc = 1 false list) so "msg" does not print

in the second case false(rc 1), !(rc 0), if(true list) now you check if rc is 0, it is and "msg" is printed.

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

#29
post #28

Earlier quoted context omitted.

$ if false; then :; else (if [ $? -eq 0 ]; then echo msg; fi); fi $ if ! false; then (if [ $? -eq 0 ]; then echo msg; fi); else :; fi msg

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 find this intuitive.

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

#30

I'm not sure what this person did expect. That bash magically parsed the output and memory of running programs, and read the user's thoughts, to determine if the state of the program indicates a condition that the user would consider an error? set -e does exactly what you'd expect, arguably, with the exception of subshells and conditions. And those rules are extremely simple to learn too. If you understand when a sta…

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"

It's explained here: https://unix.stackexchange.com/a/32251

  From help let:
  
  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise..
  
  Since var++ is post-increment, I guess the last argument does evaluate to zero. Subtle...
Post reply on HN