ip link help prints to standard error (stderr, file descriptor
2); its standard output (stdout, file descriptor
1) gets no data. Normally the two streams go to the terminal, so you cannot really tell them apart at first glance.
> affects standard output. After you use it you know any data that gets redirected must have been destined to stdout; everything else – to elsewhere: usually to stderr, although some programs print some data directly to the terminal (
ip is not one of them).
In your first case you can redirect stderr to the file descriptor of stdout, then build a pipe:
ip link help 2>&1 | grep set
2>&1 tells the shell to redirect the file descriptor
2 to whatever the file descriptor
1 points to. With this syntax, if the command printed something to stdout and stderr, everything would get to
In the second case the shell creates (if needed) and truncates the file before
ip is run. You can see this by invoking
a_command_that_doesnt_even_exist > foo.txt
foo.txt will be created despite the obvious error. This is because it's created first, before the shell even tries to run the command.
To capture stderr to the file use
2> which redirects stderr only:
ip link help 2> ip_link_help.txt
1> redirects stdout only. Short
> you used is strictly equivalent to
An artificial example of a command that prints to the terminal in three different ways is
echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty
The output is:
You can easily redirect the first two lines. Try this:
(echo "standard output"; echo "standard error" >&2; echo "terminal" >/dev/tty) >stdout.txt 2>stderr.txt
This will still print the last line though.