Bash Print Stderr Only, Not Stdout

Bash print stderr only, not stdout

Just send the stdout to null:

cmd > /dev/null

This retains stderr, but suppresses stdout.

How can I pipe stderr, and not stdout?

First redirect stderr to stdout — the pipe; then redirect stdout to /dev/null (without changing where stderr is going):

command 2>&1 >/dev/null | grep 'something'

For the details of I/O redirection in all its variety, see the chapter on Redirections in the Bash reference manual.

Note that the sequence of I/O redirections is interpreted left-to-right, but pipes are set up before the I/O redirections are interpreted. File descriptors such as 1 and 2 are references to open file descriptions. The operation 2>&1 makes file descriptor 2 aka stderr refer to the same open file description as file descriptor 1 aka stdout is currently referring to (see dup2() and open()). The operation >/dev/null then changes file descriptor 1 so that it refers to an open file description for /dev/null, but that doesn't change the fact that file descriptor 2 refers to the open file description which file descriptor 1 was originally pointing to — namely, the pipe.

Bash command that prints a message on stderr

echo something >&2 is the correct way to do what you want.

However...

This will create a little program that will echo its arguments to stderr:

gcc -o echoerr -x c - <<'EOF'
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
fprintf(stderr, "%s ", argv[i]);
}
fprintf(stderr, "\n");
exit(0);
}
EOF

You can use it like this:

$ ./echoerr this is an error message
this is an error message
$ ./echoerr this is an error message 2>error.out
$ cat error.out
this is an error message

echo that outputs to stderr

You could do this, which facilitates reading:

>&2 echo "error"

>&2 copies file descriptor #2 to file descriptor #1. Therefore, after this redirection is performed, both file descriptors will refer to the same file: the one file descriptor #2 was originally referring to. For more information see the Bash Hackers Illustrated Redirection Tutorial.

Redirect stdout to stderr but keep it also in stdout

Typically:

command | tee /dev/stderr

Is it possible to redirect stdout to a non-stderr stream inside a shell script?

For completeness, based on tripleee's comment, what I actually wanted was the following:

#!/bin/bash

echo "Send me to standard out"
echo "Send me to standard err" >&2


if ! (printf '' 1>&3) 2>&-; then
# File descriptor 3 is not open
# Option 1: Redirect fd3 to stdout.
exec 3>&1
# Option 2: Redirect fd3 to /dev/null.
# exec 3>/dev/null
fi

# No error here.
echo "Send me to stream 3" >&3

With this modification, a parent process can redirect 3 when it desires to do so, and otherwise have it as part of stdout.

$ ./Play.sh
Send me to standard out
Send me to standard err
Send me to stream 3

$ ./Play.sh 3> /dev/null
Send me to standard out
Send me to standard err



Related Topics



Leave a reply



Submit