3

I have a Bash command that produces output on STDOUT and can have an exit code of zero or non-zero.

I would like to hide the output if the exit code was non-zero and show the output if the exit code was zero, respectively.

How can this be achieved without running the command twice?

3 Answers 3

3
  • Save the output to a variable,
  • Check the return code and then
  • Print the output if it's zero

    output="$(command)"
    
    if [[ $? -eq 0 ]] ; then
        echo "$output"
    fi
    
Sign up to request clarification or add additional context in comments.

3 Comments

Note that this will not preserve the last line break correctly. I think you can fix it if you change the value of IFS.
I am using printf "$output\n" instead.
To preserve trailing newlines, you need to ensure the command substitution ends with something other than a newline, then strip the non-newlines later. To do that and preserve the exit status of command, try output=$(command; rv=$?; echo x; exit $rv). Then, echo "${output%x}".
3

The status code is only known when the process terminates. So the only way to do what you are asking, is to run the process having redirected its stdout to a temporary file, and then when it terminates, examine its status code. If it is nonzero, just delete the temporary file, if it is zero, just output the contents of the temporary file to stdout.

Here's a bash script that automates that:

#!/bin/bash

temp_file=$(mktemp)    
"$@" > temp_file
if [[ $? == 0 ]]; then
    cat "$temp_file"
fi
rm "$temp_file"

If you call this script mute then you can the command foo --bar as follows

mute foo --bar

Comments

3

You can capture an output from a command and check its exit status, without relying on the fragile $?:

if output="$(command)" ; then
    echo "$output"
fi

The pattern of decoupling the command and the test is problematic for a few reasons:

  • if your script is running with set -e, it will exit immediately when the command fails, which may not be what you want. Try it:

    #!/bin/bash
    
    set -e
    
    output="$(nonexistent_command)"
    echo "Unreachable code"
    
    if [[ $? -eq 0 ]] ; then
        echo "$output"
    fi
    
  • If you insert anything anything between the command and the test, the comparison will be wrong.

That's the gist. See the relevant ShellCheck Wiki for more.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.