#!/usr/bin/env bash # # spkg/pipestatus: run two commands in a pipeline CMD1 | CMD2 and exit # with the status of the last command to exit with a non-zero status, or # zero if no command exited with a non-zero status. # # This is useful, for example, in a Makefile, where we tee the output # of a build command to a log file. Using pipestatus, make will stop if # tee succeeds but a preceding command in the pipeline fails. # # Syntactically, the command executed is "CMD1 | CMD2" where CMD1 and # CMD2 are *not* treated as atoms. If CMD1 is "A && B" and CMD2 is "C", # then pipestatus CMD1 CMD2 will act as A && (B | C). This also implies # that CMD1 and CMD2 *MUST NOT* contain pipes, or this script will break. # # # AUTHORS: # # - Jeroen Demeyer (2010-12-19): complete rewrite (#10339) # #***************************************************************************** # Copyright (C) 2010 Jeroen Demeyer <[email protected]> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** if [ $# -ne 2 ] || [ -z "$1" -o -z "$2" ]; then echo >&2 "Usage: $0 CMD1 CMD2" echo >&2 "Run two commands in a pipeline 'CMD1 | CMD2' and exit with the status" echo >&2 "of the last command to exit with a non-zero status, or zero if no" echo >&2 "command exited with a non-zero status." exit 2 fi eval "$1 | $2; pipestatus=(\${PIPESTATUS[*]})" if [ ${pipestatus[1]} -ne 0 ]; then exit ${pipestatus[1]} else exit ${pipestatus[0]} fi