Hacker News new | ask | show | jobs
by s28l 1323 days ago
> Some scripts are better to either have explicit error handling code, or simply never fail.

Silently ignoring sub-commands that exit with a non-zero code is not the same thing as "never failing". Your script might return 0, but that doesn't mean it did what you expect it to.

> Also, don't use set -o nounset when set -u will do.

`set -o nounset` is a lot easier to understand for the next person to read the script. Yes, you can always open the manpage if you don't remember, but that is certainly less convenient than having the option explained for you.

What shell are you using that doesn't support `set -o nounset`? Even my router (using OpenWRT+ash) understands the long-form version.

> Only use that for bashisms where there's no POSIX alternative

I totally disagree. You expect people to know the difference between `[[ ... ]]` and `[ ... ]` well enough to know what the bash version is required? You expect the next person to edit the script will know that if they change the condition, then they might need to switch from `[` to `[[`?

How do you even expect people to test which of the two that they need? On most systems, `/bin/sh` is a link to `/bin/bash`, and the sh-compatibility mode of bash is hardly perfect. It's not necessarily going to catch a test that will fail in `ash` or `dash`.

I think the "YAGNI" applies to trying to support some hypothetical non-bash shell that more than 99% of scripts will never be run with. Just set your shebang to `#!/bin/bash` and be done with it.

I totally agree about `pipefail`, though. I got burned by this with condition like below: ``` if (foo | grep -Eq '...'); then ```

Since `-q` causes grep to exit after the first match, the first command exited with an error code since the `stdout` pipe was broken.

1 comments

> Silently ignoring sub-commands that exit with a non-zero code is not the same thing as "never failing".

Well I meant the former. Very useful for things like init scripts where you would prefer the script do as much as it can to get something online.

> What shell are you using that doesn't support `set -o nounset`?

You're right, this does appear to be in POSIX, so I guess it's fine. But it is unusual to see in my experience.

> You expect people to know the difference between `[[ ... ]]` and `[ ... ]` well enough to know what the bash version is required?

No, I want them to use POSIX semantics until they have to do something Bash-y. Simplicity when it doesn't cost anything extra is best practice.

> Just set your shebang to `#!/bin/bash` and be done with it.

Homebrew, Jenkins, Asdf, etc may provide their own version of Bash that is required rather than the system default, and some systems have no /bin/bash at all. So you should use #!/usr/bin/env bash for Bash scripts and #!/usr/bin/env sh for POSIX Shell scripts. This lets the user override the PATH with their required version of Bash for this script. (and the script itself can check for versions of Bash, and even re-exec itself)