I have a trivial little shell function in my setup file which invokes a commandline supplied in arguments and calls a standard exit on failure.

function my_exec() {
  if [ "$1" != "" ]; then
    $*                       # WANT FILTER HERE
    my_test $? $*
function my_test() {
  if [ $1 -ne 0 ]; then
    if [ "$1" !- "" ]; then
      my_exit "Exited with error $ecval from $*"
      my_exit "Exited with error $ecval"
function my_exit() {
  echo "ERROR: " $* 2>&1
  if [ `basename $0`  = "go.sub.sh" ]; then
    echo "ERROR" > go.sub.${occ}.done
  exit 1

One of the processes which this function executes generates a lot of output which I would like to filter.

If I could, I'd like to replace the line marked WANT FILTER HERE with something equivalent to this (the actual filter would depend on the value of the command $1):

$* | grep -v "^INFO:" | grep -v "^NOTE:"

but of course this subverts the test of $? which follows. Is there a way to filter the command output without losing the command exit code? I'd prefer not to have to redirect all the output to a file, save the status, and inverse grep the file, not least because users may be watching this job running in real time to see it progressing.

Thanks, T

  • You're using $* unquoted throughout. When you want to preserve the correct arguments in that command, you need "$@", or it would split the command on any whitespaces (by default) and apply filename globbing on all generated words. Also, there is no !- test, use [ -n "$1" ] to test whether the first positional parameter is non-empty. All expansions needs to be quoted, including the command substitution with basename.
    – Kusalananda
    Commented Dec 15, 2019 at 11:43

1 Answer 1


The bash PIPESTATUS array holds the status codes of all commands in a pipeline.

For the exit code of the 1st program:

echo "${PIPESTATUS[0]}"

exit codes of all programs piped together:

echo "${PIPESTATUS[@]}"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .