Remix.run Logo
newAccount2025 3 days ago

Why don’t all shells just do this?

inetknght 3 days ago | parent | next [-]

Perhaps you underestimate just how many scripts are poorly written and part of your operating system.

For what it's worth, I think `set -euo pipefail` should be default for every script, and thoroughly checked with shellcheck.net.

mananaysiempre 3 days ago | parent | next [-]

Take care that set -o pipefail will not work on older dash (including IIRC the current Ubuntu LTS), and neither will set -o pipefail || true if set -e is in effect. (For some reason that I’m too lazy to investigate, a failing set invocation will crash the script immediately rather than proceed into the second branch.) The best I could think of to opportunistically enable it was to use a subshell:

  if (set -o pipefail 2>/dev/null); then set -o pipefail; fi
Or you can just target bash, I guess.

(I rather dislike shellcheck because it combines genuine smells with opinions, such as insisting on $(...) instead of `...`. For the same reason, with Python I regularly use pyflakes but can’t stand flake8. But to each their own.)

koolba 3 days ago | parent [-]

> such as insisting on $(...) instead of `...`.

Only one of those can be (sanely) nested. Why would you ever want to use backticks?

oguz-ismail 3 days ago | parent [-]

Looks slick. Works on older shells too

imcritic 3 days ago | parent | prev | next [-]

That's a pitfall №60

https://mywiki.wooledge.org/BashPitfalls#set_-euo_pipefail

larkost 3 days ago | parent | next [-]

I have never liked this statement of the problem.

It is not that `set -e` is bad, it is that bash is a bit weird in this area and you have to know when things eat errors and when they don't. This is not really changed by `set -e`: you already had to know them to make safe code. `set -e` does not wave a magic wand saying you don't have to understand bash error control.

But having `set -e` is almost universally better for people who do not understand it (and I would argue also for people who do). Without it you are responsible for implementing error handling on almost every line.

As other have already said: this is one of those things that generally pushes me to other languages (in my case often Python), as the error handling is much more intuitive, and much less tricky to get right.

fireflash38 3 days ago | parent [-]

One of my major nitpicks with set -e isn't from bash... It's from poorly behaved programs you might run. Ones that don't exit with defined exit codes (non-zero on error!).

inetknght 2 days ago | parent [-]

> Ones that don't exit with defined exit codes (non-zero on error!).

My favorite is `docker images`.

It outputs... not-empty when the output is empty. It returns zero (success) when output is not-empty and empty. So you have to both do error checking and parse its output before you know whether there are any matching images in the cache.

Contrast that with grep. You can do `if grep -q foo` or `if grep -qv foo`, you can do `if "foo" == "$(grep foo)"`, etc. Much more versatile and easy to use.

Then there's apps that report to stderr that some argument isn't used but then also exits with success without doing things. Then there's similar apps that do the same thing but... exits after also doing things. Ugh.

After some time you get to learn to test your apps before you write up scripts around them. That's a good thing though, it means that you know how to mix together a diverse toolset.

javier2 3 days ago | parent | prev [-]

Well, maybe. But using `set -euo pipefail` here does not make it any worse as far as i understand? The script still does broken things, but the more correct way to be safe is not broken by set -euo pipefail

eikenberry 3 days ago | parent | prev | next [-]

What about for `/bin/sh`, i.e. posix compliant shells like dash?

chasil 3 days ago | parent | prev | next [-]

Only set -eu is defined in POSIX and supported by dash.

scns 3 days ago | parent | prev [-]

> For what it's worth, I think `set -euo pipefail` should be default for every script, and thoroughly checked with shellcheck.net.

This

koolba 3 days ago | parent | prev | next [-]

Automatically leaking the line number and command, even to stderr is not a sane default.

eastbound 3 days ago | parent | next [-]

Is that a safety point of view? Is shell supposed to be input-safe? I may have limited shell skills but it doesn’t seems like it’s designed to be safe.

fireflash38 3 days ago | parent | prev [-]

Why? It's not like you couldn't get the source of the running script anyway.

forrestthewoods 3 days ago | parent | prev | next [-]

Because shells weren’t supposed to be doing complex logic. People use shells to do way way way more than they should.

3 days ago | parent | prev [-]
[deleted]