In bash we have 3 stream types:
0 (STDIN)
1 (STDOUT)
2 (STDERR)
So, while executing some program i can use these streams (e.g. i can redirect them from console to a file or smth like /dev/null, etc):
# only errors from STDERR will be shown, STDOUT will be moved to /dev/null
command > /dev/null
# only STDOUT will be shown, STDERR will be moved to /dev/null
command 2> /dev/null
I saw that some people write
command &> /dev/null
What is the difference between > and &> in bash?
what is the difference between ">" and "&>" in bash?
It's a bashism that redirects both stdout and stderr. It can also be achieved with the more portable:
command > file 2>&1
Related
I'm executing a program that dumps crash report into STDERR from where I have to filter some necessary information. The problem is that I'm unable to redirect STDERR to STDOUT and PIPE it with grep
command 2>&1 >/dev/null | grep "^[^-]" >& /tmp/fl
Getting error: Ambiguous output redirect.
Same command works under bash terminal.
What should I change to make it work ?
csh is significantly more limited than bash when it comes to file redirection. In csh, you can redirect stdout with the usual > operator, you can redirect both stdout and stderr with the >& operator, you can pipe stdout and stderr with the |& operator, but there is no single operator to redirect stderr alone.
The usual workaround is to execute the command in a sub-shell, redirecting stdout in that sub-shell to whatever file you want (/dev/null in this case), and then use the |& operator to redirect stdout and stderr of the sub-shell to the next command in the main shell.
In your case, this means something like:
( command >/dev/null ) |& grep "^[^-]" >&/tmp/fl
Because stdout is redirected to /dev/null inside the sub-shell, the |& operator will end up acting as 2>&1 in bash - since stdout is discarded in the sub-shell, nothing written to stdout will ever reach the pipe.
If you dont mind mixing stdout and stderr into the pipe you can use
command |& grep "^[^-]" >& /tmp/fl
Otherwise you can do the hack:
(command >/dev/null) |& grep "^[^-]" >& /tmp/fl
which separates out stdout to null, then piping stdout and stderr just gives
stderr as content.
Nohup redirects stderr to stdout if it points to a terminal. But I want to retain stderr output to the terminal
Is there a way to accomplish that? Is there an alternative?
I don't know if I understood correctly or not.
you mean that you don't want to see the error in terminal?
if yes:
if you want to save the error in file:
nohup command 2> file.txt
if you don't need the errors:
nohup command 2> /dev/null
2 means the error output of command
2> file.txt means write the error output to the file.txt
Just redirect it somewhere else, so it's not the terminal:
nohup bash -c 'echo OUT ; echo ERR >& 2' 2> err
You can redirect the stderr back to stdout instead of to a file to keep the output in the terminal, but it doesn't make much sense: nohup is for situations where the terminal might get lost, in which case you'll lose the stderr.
nohup bash -c 'echo OUT ; echo ERR >& 2' 2> >(cat)
I have a question for redirection.
I always use anycommands > /dev/null 2>&1 when I need not any output. But I have never used anycommands 2> /dev/null >&2
Question: Which one is the best way to expect no outputs? What's the difference between anycommands > /dev/null 2>&1 and anycommands 2> /dev/null >&2
case#1:(echo stdout;echo stderr>&2) >/dev/null 2>&1
stdout(1) is replaced by an fd to /dev/null
stderr(2) descriptor is copied from &1 which now is an fd to /dev/null
result: no output at all
case#2:(echo stdout;echo stderr>&2) 2>&1 >/dev/null
stderr(2) descriptor is copied from &1 which is the default stdout
stdout(1) is replaced by an fd to /dev/null
result: stderr is empty, stdout not shown, stderr on stdout
case#3: (echo stdout; echo stderr >&2) 2> /dev/null >&2
same as case#1, stderr and stdout have switched roles
Effectively, the two are equivalent. cmd > /dev/null 2>&1 connects stdout of the command to /dev/null, and then connects stderr to the same file. cmd 2>/dev/null >&2 connects stderr to /dev/null, and then connects stdout to it. The only difference is in the order in which the two streams are associated with /dev/null, which has no bearing on the status of the command when it is run. In both cases, both streams are redirected to the bit bucket.
If you're using only BASH, use &> to redirect both stdout and stderr. That's the most compact, safe and simple solution.
Regarding your question, the first one is equivalent to &> (it redirects both stdout and stderr to /dev/null.
The second connects stderr to /dev/null and redirects stdout to the new stderr, so it's equivalent to as far as the output is concerned. Just the order of file descriptor operations is reversed.
I have checked couple of relevant posts regarding this in stackoverflow and other sources regarding the usage of 2>&1.
Unfortunately so far have not get my head around it completely.
I understand that 2 is the stderr and 1 is the stdout and we are combining with the 2>&1.
But my question is what is difference between:
1. mycommand > /dev/null
2. mycommand 2> /dev/null
3. mycommand > /dev/null 2>&1
I was thinking:
will redirect stdout and stderr to /dev/null
will redirect stderr to /dev/null
will redirect stdout and stderr to /dev/null
Relevant posts:
What does "/dev/null" mean at the end of shell commands)
i/o stream redirection on linux shell. how does the shell process a command with redirection?
What does “> /dev/null 2>&1″ mean? (http://www.xaprb.com/blog/2006/06/06/what-does-devnull-21-mean/)
See this:
mycommand > /dev/null
it will redirect channel 1 (which is stdout) of mycommand to /dev/null
mycommand 2> /dev/null
it will redirect channel 2 (which is stderr) to /dev/null
mycommand > /dev/null 2>&1
it will redirect channel 1 to /dev/null and then bind channel 2 (stderr) to channel 1 (stdout). Both will go into /dev/null
There is another one (just to complete)
mycommand 2>&1 > /dev/null
In this second case, I bind (the child's) stderr to stdout (of the
parent) and then I find the child's stdout to /dev/null. The result is
that you now get the child's stderr output on stdout and the stdout
goes to the file. This is useful for processing stderr in a pipe, for
example. (see this answer)
(errfile doesn't exist)
$ cat errfile
cat: 0652-050 Cannot open errfile.
$ cat errfile > /tmp/stream.out
cat: 0652-050 Cannot open errfile.
$ cat errfile > /tmp/stream.out 2>&1
$ cat /tmp/stream.out
cat: 0652-050 Cannot open errfile.
($ rm /tmp/stream.out)
$ cat errfile 2>&1 > /tmp/stream.out
cat: 0652-050 Cannot open errfile.
$ cat /tmp/stream.out
$
Order is thus important and 2>&1 1>out is different than 1>out 2>&1 due to stream redirection at shell interpretation. You shoud redirect in "reverse" order. stdout > final than source > stdout
Try these to get the differences:
echo "stderr" > /dev/fd/2 | >/dev/null
stderr
echo "stdout" > /dev/fd/1 | >/dev/null
both commands redirected to /dev/null but in first one we're writing to stderr which prints stderr but in second one it prints nothing
1: redirect STDOUT to /dev/null, you use default file descriptor in this case, e.g. command [default]> filename, the default file descriptor is STDOUT.
2: redirect STDERR to /dev/null
3: redirect STDOUT to /dev/null and redirect STDERROR to STDOUT, which means both STDOUT and STDERROR will be redirected to /dev/null
Hope the tips make you clear.
0, 1, 2...9 are file descriptors in bash. 0 stands for stdin, 1 stands for stdout, 2 stands for stderror. 3~9 is spare for any other temporary usage.
Any file descriptor can be redirected to other file descriptor or file by using operator > or >>(append).
Usage: >
Please reference to http://www.tldp.org/LDP/abs/html/io-redirection.html
I would like to redirect the output generated from a background application in Linux to /dev/null.
I am using kate text editor and it prints all the debug messages on the terminal which I would like to redirect to /dev/null.
Any idea how to do it ?
Thanks
You use:
yourcommand > /dev/null 2>&1
If it should run in the Background add an &
yourcommand > /dev/null 2>&1 &
>/dev/null 2>&1 means redirect stdout to /dev/null AND stderr to the place where stdout points at that time
If you want stderr to occur on console and only stdout going to /dev/null you can use:
yourcommand 2>&1 > /dev/null
In this case stderr is redirected to stdout (e.g. your console) and afterwards the original stdout is redirected to /dev/null
If the program should not terminate you can use:
nohup yourcommand &
Without any parameter all output lands in nohup.out
These will also redirect both:
yourcommand &> /dev/null
yourcommand >& /dev/null
though the bash manual says the first is preferred.