How to suppress a command's output but show it if the command exit codes an error?
Unfortunately, the assumption that
stderr is only used for error output isn't always correct. Rather,
stderr is often used for any and all interactive output and diagnostics, i.e. output intended for the user to read in an interactive prompt1.
dd are well-known examples.
Some commands will provide a flag (e.g.
-silent) to suppress non-error output - read their man pages to see if one exists.
Another convention that holds more often is the exit code: a program returns an exit code when it exits. Typically2, an exit code of
0 indicates success, and any other exit code indicates an error.
bash, you can get the exit code of the last command from the
$? variable. In
fish, use the
$status variable. You can pipe
stderr to a temporary file and only print it if an error occurs. For example (
command 2>/tmp/outputbuffer if $status cat /tmp/outputbuffer rm /tmp/outputbuffer
You can also use some shortcuts, if you aren't chaining commands:
if command 2>/tmp/outputbuffer cat /tmp/outputbuffer rm /tmp/outputbuffer
command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;
You can also pipe
stdout to the same buffer by using
(Note: I don't actually know
fish, so I'm adapting the concept to what I can find in its documentation. The syntax might be slightly wrong. Also, you can use
mktemp to generate a unique temporary file - run it and record the filename in a variable.)
If you need to run the whole thing in the background of a shell you are also using interactively at the same time, then you're better off writing a script to handle the output-hiding and running that script in the background with the standard techniques (
fish). Heck, you can put something like the following function in
function run-silent set temp (mktemp) if $argv 2>&1 >$temp cat $temp rm $temp end
run-silent somecommand & (where the trailing
& causes it to run in the background)
Note that this will swallow the original exit code, and will dump both
stderr in the event of a failure. You can customise it as necessary.
1 There isn't even a guarantee that error output won't appear on
stdout - some programs will dump all output there!
2 Unfortunately, this still isn't always the case - the exit code is completely controlled by the program, and some will indicate some success conditions with non-zero exits. Again, check the manual.
Unix utilities send general messages to
stdout, and error messages to
stderr, so if we only want to see error messages, then it will be sufficient to suppress
stdout so only
stderr gets output to the console.
The way to do this (in both
fish) is to append
>/dev/null to the command. This pipes stdout into nothingness, but stderr (with your error messages) still comes through to the console.
So for instance:
echo 1 >/dev/null prints nothing, because the normal
stdout output is suppressed, and nothing was written to stderr.
man doesnotexist >/dev/null prints an error message, because
man writes its error message to
This will run the command in the background and write errors to a log file whilest ignoring normal output
command > /dev/null 2> /tmp/example_error.log &