Live data from Hacker News

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

mywiki.wooledge.org

81–90 of 114 posts

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

#81
A lot of commenters suggesting "pipefail" aren't realising the full extent of the problem. Here's an example that might be clearer, from https://david.rothlis.net/shell-set-e

This prints “a”, as you’d expect:

    set -e
    myfun() { printf a; false; printf b; }
    myfun
    printf c
...because the “set -e” terminates the whole script immediately after running the “false” command.

But this script prints “a-b-True”, where some people (myself included) might have expected it to print “a-False”:

    set -e
    myfun() { printf a-; false; printf b-; }
    if myfun; then
        printf True
    else
        printf False
    fi
The “set -e” is ignored completely. Putting another “set -e” inside the definition of myfun doesn’t make any difference.

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

#82
post #71

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.

> Because bash is thousand blades and no handle. FTFY. It really is absolutely terrible tool as programming language. If your script is more than "a bunch of pipes in a trench coat" just use something else. I'd unironically prefer Perl to it.

The final straw for me was when I (described in my blog post) realized that not even "foo | bar" does the right thing.

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

#83
post #3

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…

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.

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

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

#84
post #3

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…

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

They could sing Daisy Daisy together.

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

#85

A lot of commenters suggesting "pipefail" aren't realising the full extent of the problem. Here's an example that might be clearer, from https://david.rothlis.net/shell-set-e This prints “a”, as you’d expect: set -e myfun() { printf a; false; printf b; } myfun printf c ...because the “set -e” terminates the whole script immediately after running the “false” command. But this script prints “a-b-True”, where some peopl…

[deleted]

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

#86

Earlier quoted context omitted.

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 $?" ;…

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.

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

#87
post #48

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…

Whenever I need a quick script I use bash. If that script goes beyond 20 lines or has anything but the simplest `if` or `&&`, I've learned time and time again that I should rewrite it (python for example)

Google agrees

https://google.github.io/styleguide/shellguide.html

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

#88
post #55

set -euo pipefail This is how all of my shell scripts start.

These options are addressed in the post, and they are very far from fixing the problem.

Yes, they are better than nothing. But as explained in the article it's still like wandering blindfolded into a minefield.

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

#89
post #79

What's the best and smallest choice to replace admin/ops bash scripts ? Python ? Python with some lib ? Ruby ? Lua ? Rust ?

IMO, Perl is perfect for this purpose. A good thing about Perl is, it doesn't really changed any more. So no need to spend time keeping up with latest developments like Ruby or Rust.

> it doesn't really changed any more

it does change, it just has outstanding backward compatibility and new feature (including parser-level) opt-in per module.

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

#90

A lot of commenters suggesting "pipefail" aren't realising the full extent of the problem. Here's an example that might be clearer, from https://david.rothlis.net/shell-set-e This prints “a”, as you’d expect: set -e myfun() { printf a; false; printf b; } myfun printf c ...because the “set -e” terminates the whole script immediately after running the “false” command. But this script prints “a-b-True”, where some peopl…

It's always been odd that Bash has hundreds of options for controlling its behaviour in non-standard ways, via "set", "shopt" and environment variables, but it's never had an option to make "-e" do the obviously natural behaviour,,

I encountered the "you can't enable -e" problem years ago in a complex build system that used Bash to build embedded sysem components. The scripts were all designed on the assumption that "set -eu -o pipefail" would cause early exit on any failing commands as if doing the equivalent of "exit $?" or "return $?", and of course it is not reliable, as your example shows.

The very surprising behaviour of "set -e" inside functions was not noticed for a long time while the system was being written and used. When it was noticed, "set -e" was added inside the functions because that seemed to work for the Bash version at the time, then later it stopped working.

Post reply on HN