To our delight, pipefail has been standardized in POSIX and implemented in all POSIX shells. However, PIPESTATUS (pipestatus for zsh) is only available in bash and zsh. This project will make PIPESTATUS available to all POSIX shells.
- Supports
pipefailbehavior - Support for
errexitshell option - No global variables except
PIPESTS - All POSIX shells supported
- sh, bash, ksh, zsh, etc.
- Shortest code possible
- Extra: Function to ignore
SIGPIPE(igpipe)
Note: The Bourne shell is not supported because it is legacy, not POSIX compliant, and no longer used.
This replaces the old FAQ (How do I get the exit code of cmd1 in cmd1|cmd2) on comp.unix.shell.
Use it as:
# From
cmd1 | cmd2 | cmd3
# To
pipe 'cmd1 | cmd2 | cmd3' "$@"
# or
pipe -fail 'cmd1 | cmd2 | cmd3' "$@"
# exit codes are in
echo "$? and $PIPESTS" # => 0 and 0 0 0Note: sh-pipestatus separates each command in the pipeline with <whitespace>|<whitespace> (whitespace: space, tab, newline). Therefore, if part of a command contains this delimiter, it will be misinterpreted. To avoid this, use the following instead or shell functions.
# From
pipe 'echo "foo | bar" | tr a-z A-Z'
# To
pipe 'echo "foo ""| bar" | tr a-z A-Z'# From
pipe 'echo "foo" | case $1 in x | y) cat ;; esac | tr a-z A-Z' x
# To
pipe 'echo "foo" | case $1 in x|y) cat ;; esac | tr a-z A-Z' x# From
pipe 'echo $((1 | 2)) | tr 3 C'
# To
pipe 'echo $((1|2)) | tr 3 C'When you enable pipefail, you will probably be plagued by SIGPIPE. The igpipe function is for ignoring SIGPIPE.
set -o pipefail
seq 100000 | cat | head >/dev/null
echo $? # => 141
igpipe seq 100000 | igpipe cat | head >/dev/null
echo $? # => 0