1

I want strict mode in my scripts. I would also appreciate portability.

set -o pipefail seems compulsory. Yet shellcheck(a static linter) is unhappy that "In POSIX sh, set option pipefail is undefined".

Is it correct? If so, is this a bash solely feature or is it rather prolific?

6

The pipefail shell option is specific to a number of shells that shellcheck claims to support1. You can use this shell option and be portable, if by "portability" you assume that any target system has a shell that supports it (and any other constructs that you may be using). This is the same type of "portability" that you get with any other specific scripting language.

The shellcheck linter will complain if it finds set -o pipefail in a shell script that is a sh script, since it's currently not supported by POSIX sh.

To ensure that your script is a script interpreted by the bash shell (or any specific shell that you are coding for), the script should have a #!-line pointing to the correct shell interpreter, e.g.,

#!/bin/bash

or possibly

#!/usr/bin/env bash

or something similar.

With a proper #!-line that additionally indicates that the script will be interpreted by a particular shell that is not sh, the shellcheck linter will not complain about you setting the pipefail shell option in your script.

If you don't use a #!-line in your scripts, then you should consider doing so (or always run your scripts with an explicit interpreter on the command line). Meanwhile, the shellcheck command line tool can be told to switch to mode using its -s (or --shell=) option:

shellcheck --shell=bash myscript

1I suspect that shellcheck has a "POSIX sh mode" and an "other mode" to support bash, dash, and ksh (shellcheck does not claim to support zsh). The pipefail shell option is documented to work with bash, and ksh. The zsh shell has a PIPE_FAIL shell option that can be set in the same way. The dash shell does not support the option, but if the #!-line mentions dash, shellcheck won't complain about pipefail.

4
  • It does not complain if using ksh or dash only sh. For sh it is on from v0.7. (If I read this correctly) On my system set -o pipefail has effect on bash, ksh, zsh albeit strange error code in ksh (93u+) - fails (as expected) with sh, dash, tcsh ... – ibuprofen Jun 19 at 11:46
  • @ibuprofen I suspect that shellcheck has a "POSIX sh mode" and an "other mode". The pipefail shell option is documented to work with bash, and ksh. The zsh shell has a PIPE_FAIL shell option that can be set in the same way. Dash does not support the option. – Kusalananda Jun 19 at 13:20
  • 1
    In zsh, case and underscores are ignored in option names, so set -o pipefail works as well. In yash, that's case, underscores or hyphens, so set -o PIPE_FAIL, set -o PIPE-FAIL or set -o --pipefail (but also set --pipe-fail) would also work. In bash, case is significant and underscore/hyphens are not ignored. bash also has 2 sets of options, one set with set -o, the other with shopt -s. Some of the ones set with set -o can also be passed as bash --option, but not pipefail. – Stéphane Chazelas Jun 19 at 20:59
  • Such a simple solution. Such a comprehensive answer. Thanks! – Vorac Jun 20 at 1:14
6

The pipefail option comes from ksh93 and is also present in a few other shells. It was added:

A request to add it to the POSIX standard was submitted in 2013 and a resolution accepted in 2019. So it will be in the next major revision of the standard due soon (2022 at the latest).

It will still probably take some more time for remaining implementations (mostly dash, bosh and ksh88-based shells) to add support for it. After which the "EOL" clock will start ticking and 10 years later you'll be able to assume all sh implementations on currently supported systems will support it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.