Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

All set -e does is halt further execution of your script if any line exits above 0. There is really nothing bash can do about this. It can't perform a psychological evaluation on why a program is not giving the expected output. And most of the time, when something fails, if it were made by a less than serious programmer (like myself) they don't bother to exit on error correctly with a code above zero. But if you are building a script collection, or python utility or even an binary, simply exit 1 if you encounter a general error. Then further up the chain in your shell scripts the error can be handled properly. There are more specific error codes you can use that might be helpful to your shell script.

If you are wondering what in the world I'm talking about and I've missed your question entirely, sorry about that. My feet are tired.



> All set -e does is halt further execution of your script if any line exits above 0.

This is the expectation, and the article is about why it's not that simple.


The `let ++` example is pretty damning. I find Bash to be a poor and outdated shell that we’re stuck with for now. Its design is the best argument against LSD I know, it came out of the hippie drug days, and Bash reflects that with its madness.


A lot of the sins of shell are from it's primary role as an interactive interface to the computer. it's use as a scripting language was a nice secondary goal.

On the one hand it is nice to have your interactive interface and your scripts be the same language. on the other it is a bit horrifying the way all those convenient interactive features make your programs so prone to failure.


We'd probably all be better off if our scripts weren't in the same language as used by our interactive interface. I do paste snippets of scripting (if, for, etc.) into my interactive terminal from time to time, but that's rare compared to just typing commands to run.

I wouldn't mind it if all scripting in the shell had to be offloaded to a completely separate language that was less error prone and more consistent.


Interesting.. that might be part of why I fell in love with this ugly monster called Bash scripting.


> The `let ++` example is pretty damning.

Seems kind of logical, the following c code behaves the same way.

  #include <stdio.h>

  int test(void) {
          int i=0;
          return i++;
  }
  
  void main(void) {
          printf("i = %d\n", test());
  }
'let i++' evaluates to / returns 0 before increasing i, just like c would.


I don't mean what it returns, I mean that returning non-zero trips up Bash into thinking it's a non-successful error code. The fact that doing math can trip up error detection implies a fundamental design flaw of the system. Which, I mean, we're in Bash, of course it's poorly designed. I didn't know it was quite this bad though.


Also, error messages to stderr, please, and bonus points for not trying to emit cute ansi color codes unconditionally


CI tools: telling you who the asshole is, since 2001.


Bash is the only language I know where

  if cond; then x; else y; fi
does not do the same thing as

  if ! cond; then y; else x; fi
despite the the absence of any operator overloading.


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


Your original claim is disingenuous.

Of course

  cond = false
  if cond; then x; else (if cond; then echo msg); fi
does not do the same thing as

  cond = true
  if cond; then (if cond; then echo msg); else x; fi
Bash is not somehow strange in this regard.


There's neither anything disingenuous about my claim. Bash's behavior is quite unique and unexpected to most people in the examples I showed. And I don't appreciate the attack.


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 $?


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


Yep that's a valid scenario, if you need more granularity than just fail or success then you will have to use a different method, e.g.

Status=0

Somecommand || status=$?

Then do logic based on status


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.


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.


> 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.


Whoops, that's what I get for writing these when I'm sleepy. Yes of course ! doesn't always set the result to success, that wouldn't make any sense. I misspoke in that part. I meant to say Bash treats it like any other command that modifies $?, instead of treating it specially and preventing it from modifying that variable. Thanks.


Isn’t sql an other one?


how long until there's an AI advanced enough to give psychological evaluation to other programs?

/joke


They could sing Daisy Daisy together.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: