binfalse() { $binfalse || return 1 # normalize return value } if [ -x /usr/bin/true ]; then bintrue=/usr/bin/true elif [ -x /bin/true ]; then bintrue=/bin/true else bintrue=true fi if [ -x /usr/bin/false ]; then binfalse=/usr/bin/false elif [ -x /bin/false ]; then binfalse=/bin/false else binfalse=true fi shopt -s lastpipe unset foo bar echo a b c | read foo echo after 1: foo = $foo unset tot declare -i tot printf "%d\n" 1 2 3 | while read foo; do tot+=$foo; done echo after 2: tot = $tot unset bar echo g h i | bar=7 echo after: $bar unset foo last printf "%s\n" a b c | while read foo; do last=$foo; done echo last = $last exit 142 | false echo $? -- ${PIPESTATUS[@]} true | false | $bintrue echo $? -- ${PIPESTATUS[@]} true | $bintrue | false echo $? -- ${PIPESTATUS[@]} set -o pipefail true | $bintrue | false echo $? -- ${PIPESTATUS[@]} true | binfalse | true echo $? -- ${PIPESTATUS[@]} set +o pipefail ${THIS_SH} ./lastpipe1.sub echo lastpipe1.sub returns $?