Reputation: 91
I'm a bit confused as to why when I'm redirecting the standard output of an echo command to the standard error, why I still get the argument printed in the terminal?
Here's is the line I ran
echo "potato" >&2
Could someone explain this to me? How does this command output anything, if the output was redirected somewhere else?
Thank you :)
Upvotes: 0
Views: 602
Reputation: 4504
At first, when your terminal and shell starts, both STDOUT and STDERR points to the terminal output. Your command echo "potato" >&2
is asking to redirect STDOUT to what STDERR points to. Thus this command has no effect at all.
Here's some references:
> somefile
or 1> somefile
redirects file descriptor 1 to the file named 'somefile', i.e. pointing STDOUT to 'somefile'n> somefile
redirects file descriptor n to the file named 'somefile', where n
= 1, 2, 3, ... n
by default is 1, when n
is omitted.n>&m
redirects file descriptor n to file descriptor m.n>&-
closes file descriptor n, where n = 1, 2, 3, ...# FD1 (file descriptor1, i.e. STDOUT) is redirected (pointing) to the file named 'file.log`
# Then FD2 is pointing to what FD1 points to, i.e. 'file.log'. Thus the following command
# redirection both "potato" and the error output of 'ls xx' to file.log:
$ (echo "potato"; ls xx) > file.log 2>&1
$ cat file.log
potato
ls: cannot access xx: No such file or directory
# FD2 is redirected (pointing) to what FD1 points to, i.e. the terminal output. (This has no effect, since FD2 was pointed to the terminal anyway.
# FD1 is then redirected to file.log
# Thus the following command only redirects "potato" to file.log, and left the error message
# displayed on the terminal.
$ (echo "potato"; ls xx) 2>&1 > file.log
ls: cannot access xx: No such file or directory
$ cat file.log
potato
command1 > /dev/null | comamnd2
first create pipe between command1, and command2, i.e. link STDOUT of command 1 to STDIN of command2. Then, STDOUT of command1 is redirected to /dev/null. This essentially cancels the pipe (disengages the pipe). Thus command2 will sees end of the STDIN input, i.e. STDIN of command2 is closed.So, it explains why the following command exchanges STDIN and STDOUT:
$ (echo xx; ls xx) 3>&1 1>&2 2>&3 3>&- | wc -l
ls: cannot access xx: No such file or directory
1
wc
points to pipe-inThe net effects are:
FD1 now points to the terminal output.
FD2 now points to the pipe-out, piping outputs to wc
command.
Hope this helps.
Upvotes: 1
Reputation: 11603
The output is simply going where it's told to go
By default file descriptor 1 and 2 point to the same location (note >&2
is equivalent to 1>&2
)
> $ ls -l /proc/$$/fd/
total 0
lrwx------ 1 foo foo 64 Dec 23 18:42 0 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 1 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 2 -> /dev/pts/3
And now let's say we redirect one of those file descriptors to point elsewhere
> exec 1>foo
> ls -l /proc/$$/fd/
> exec 1>&2
> cat foo
total 0
lrwx------ 1 foo foo 64 Dec 23 18:42 0 -> /dev/pts/3
lrwx------ 1 foo foo 64 Dec 23 18:42 1 -> /home/foo/foo
lrwx------ 1 foo foo 64 Dec 23 18:42 2 -> /dev/pts/3
Note the output of ls -l /proc/$$/fd/
went to file foo
in our working directory rather than being printed to stdout.
Upvotes: 0
Reputation: 131
I think what you want is:
bash-3.2$ echo "potato" &>2
bash-3.2$
From the man
page for bash:
Redirecting Standard Output and Standard Error
Bash allows both the standard output (file descriptor 1) and
the standard error output (file descriptor 2) to be redirected to the file
whose name is the expansion of word with this construct.
There are two formats for redirecting standard output and standard error:
&>word
and
>&word
Of the two forms, the first is preferred. This is semantically equivalent to
>word 2>&1
Upvotes: 1
Reputation: 4189
Because standard error is also displayed in terminal by default. So you redirect your standard output to standard error which in turn gets redirected to the console. The result does not change.
Upvotes: 0
Reputation: 406
Well, by default, your terminal shows both STDOUT and STDERR.
So, what you are seeing is STDERR.
If you want to hide STDERR: echo "potato" 2>/dev/null >&2
/dev/null
is a black-hole, where you can redirect stuff you have no wish to see :)
Upvotes: 0