How can I redirect STDERR to STDOUT, but ignore the original STDOUT?
This question already has an answer here:
- How to pipe stderr, and not stdout? 12 answers
I have a program whose STDERR
output I want to inspect and run grep
on etc.
So I could redirect it to STDOUT
and use grep, but the problem is, I do not want the original STDOUT
content.
So, this one won't do
cmd 2>&1 | grep pattern
because it will mix the original STDOUT and STDERR.
And this one doesn't work since grep doesn't read the STDERR output:
cmd 1>/dev/null | grep pattern
But also, this one won't work:
cmd 1>/dev/null 2>&1 | grep pattern
because the output will be completely empty, since everything gets written to /dev/null
.
But there must be a simple way to do it?
What does not work:
The reason the last command you quoted:
cmd 1>/dev/null 2>&1 | grep pattern
does not work, stems from a confusion on the order in which redirection works. You expected the last quoted redirection to be applied to the ones before it on every output, so that output the original standard output file descriptor (1) will go to /dev/null, and output to the standard error file descriptor (2) will go to the original standard output.
However, this is not how shell redirection works. Each redirection causes the file descriptors to be "remapped" by closing the "source" and duplicating the "destination" into it (see the man
pages of dup(2)
and close(2)
), in order. This means that in your command standard output is first replaced with /dev/null
, and then standard error replaced with standard output, which is /dev/null
already.
What works:
Therefore, to obtain the desired effect, you just need to reverse the redirections. Then you will have standard error go to standard output, and the original standard output go to /dev/null
:
cmd 2>&1 >/dev/null | grep pattern
(note that the 1
before >
is unnecessary - for output redirection standard output is the default)
Addendum: Charlie mentioned redirecting to &-
to close a file descriptor. If using an interactive shell which supports that extension (bash
and some other implementations do but not all and it is not standard), you can also do it like this:
cmd 2>&1 >&- | grep pattern
This may be better - it can save some time, because when the command tries to write to standard output the call to write
may fail immediately without waiting for a context switch into the kernel and the driver handling /dev/null
(depending on the system call implementation - some may catch this in the libc
function, and some may also have special handling for /dev/null
). If there is a lot of output that can be worthwhile, and it's faster to type.
This will mostly work because most programs do not care if they fail to write to standard output (who really checks the return value of printf
?) and will not mind that standard output is closed. But some programs can bail out with a failure code if write
fails - usually block processors, programs using some careful library for I/O or logging to stdandard output. So if it doesn't work remember that this is a likely cause and try /dev/null
.
Close STDOUT first:
1>&-, >&-
See here.
I would try something simple like:
cmd 2> tmp_file && cat tmp_file | grep pattern && rm -f tmp_file
ReferenceURL : https://stackoverflow.com/questions/549737/how-can-i-redirect-stderr-to-stdout-but-ignore-the-original-stdout
'programing' 카테고리의 다른 글
typescript에서“not-type of parameter에 할당 할 수 없음”오류는 무엇입니까? (0) | 2020.12.24 |
---|---|
makefiles-모든 c 파일을 한 번에 컴파일 (0) | 2020.12.24 |
Javascript Engines Advantages (0) | 2020.12.24 |
UriFormatException : 잘못된 URI : 잘못된 포트가 지정되었습니다. (0) | 2020.12.24 |
__init__를 호출하지 않고 클래스를 인스턴스화하는 방법이 있습니까? (0) | 2020.12.24 |