stdout이 아닌 stderr을 파이프하는 방법은 무엇입니까?
나는 stdout
및에 정보를 쓰는 프로그램을 가지고 있으며 stderr
, stdout 은 무시하면서 stderr에grep
오는 것을 통해 해야합니다 .
물론 2 단계로 할 수 있습니다.
command > /dev/null 2> temp.file
grep 'something' temp.file
하지만 임시 파일없이이 작업을 수행하는 것을 선호합니다. 현명한 배관 트릭이 있습니까?
먼저 stderr을 stdout-파이프로 리디렉션합니다. 그런 다음 stdout을 /dev/null
(stderr이가는 곳을 변경하지 않고) 리디렉션합니다 .
command 2>&1 >/dev/null | grep 'something'
다양한 I / O 리디렉션에 대한 자세한 내용은 Bash 참조 매뉴얼의 리디렉션 에 대한 장을 참조하십시오 .
I / O 리디렉션 시퀀스는 왼쪽에서 오른쪽으로 해석되지만 파이프는 I / O 리디렉션이 해석되기 전에 설정됩니다. 1 및 2와 같은 파일 설명자는 열린 파일 설명에 대한 참조입니다. 이 작업 2>&1
은 파일 설명자 2 (일명 stderr)가 파일 설명자 1 (일명 stdout이 현재 참조하는 파일 설명)과 동일한 열린 파일 설명을 참조하게합니다 ( dup2()
및 참조 open()
). >/dev/null
그런 다음 이 작업 은에 대한 열린 파일 설명을 참조하도록 파일 설명자 1을 변경 /dev/null
하지만 파일 설명자 2가 파일 설명자 1이 원래 가리키는 열린 파일 설명, 즉 파이프를 참조한다는 사실은 변경되지 않습니다.
또는 stderr 및 stdout의 출력을 사용하여 교체하려면 다음을 수행하십시오.
command 3>&1 1>&2 2>&3
이렇게하면 새 파일 설명자 (3)가 생성되고 1 (stdout)과 동일한 위치에 할당 된 다음 fd 1 (stdout)이 fd 2 (stderr)와 동일한 위치에 할당되고 마지막으로 fd 2 (stderr)가 동일한 위치에 할당됩니다. fd 3 (stdout)으로 배치하십시오. Stderr는 이제 stdout 및 stderr에 보존 된 이전 stdout으로 사용할 수 있습니다. 이것은 과잉 일 수 있지만 bash 파일 설명자에 대한 자세한 내용을 제공 할 수 있습니다 (각 프로세스에 9 가지 사용 가능).
Bash에서는 프로세스 대체를 사용하여 서브 쉘로 리디렉션 할 수도 있습니다 .
command > >(stdlog pipe) 2> >(stderr pipe)
당면한 경우 :
command 2> >(grep 'something') >/dev/null
다음과 같은 경우 이러한 답변의 최고를 결합합니다.
command 2> >(grep -v something 1>&2)
... 그러면 모든 stdout은 stdout으로 보존 되고 모든 stderr은 stderr로 보존되지만 stderr에는 문자열 "something"이 포함 된 행이 표시되지 않습니다.
이것은 stdout과 stderr을 되돌 리거나 버리지 않고, 그것들을 함께 뭉치거나, 임시 파일을 사용하지 않는다는 독특한 장점이 있습니다.
"리디렉션"과 "파이프"에서 실제로 무슨 일이 일어나고 있는지 생각하면 사물을 시각화하는 것이 훨씬 쉽습니다. bash의 리디렉션 및 파이프는 한 가지 작업을 수행합니다. 프로세스 파일 설명자 0, 1 및 2가 가리키는 위치를 수정합니다 (/ proc / [pid] / fd / * 참조).
때 파이프 또는 "|" 연산자가 명령 줄에 존재하면 bash가 fifo를 생성하고 왼쪽 명령의 FD 1이이 fifo를 가리키고 오른쪽 명령의 FD 0이 동일한 fifo를 가리 킵니다.
다음으로 각 측면의 리디렉션 연산자 가 왼쪽에서 오른쪽으로 평가 되고 설명자가 중복 될 때마다 현재 설정이 사용됩니다. 이것은 파이프가 먼저 설정 되었기 때문에 FD1 (왼쪽)과 FD0 (오른쪽)이 일반적으로 사용하던 것과 이미 변경되었으며 이들의 복제는 그 사실을 반영하기 때문에 중요합니다.
따라서 다음과 같이 입력 할 때 :
command 2>&1 >/dev/null | grep 'something'
다음은 순서대로 발생합니다.
- 파이프 (fifo)가 생성됩니다. "command FD1"은이 파이프를 가리 킵니다. "grep FD0"도이 파이프를 가리 킵니다.
- "command FD2"는 "command FD1"이 현재 가리키는 곳 (파이프)을 가리 킵니다.
- "command FD1"은 / dev / null을 가리 킵니다.
따라서 "command"가 FD 2 (stderr)에 쓰는 모든 출력은 파이프로 이동하여 다른 쪽의 "grep"에 의해 읽 힙니다. "command"가 FD 1 (stdout)에 쓰는 모든 출력은 / dev / null로 이동합니다.
대신 다음을 실행합니다.
command >/dev/null 2>&1 | grep 'something'
다음과 같은 일이 발생합니다.
- 파이프가 생성되고 "command FD 1"및 "grep FD 0"이 해당 파이프를 가리 킵니다.
- "command FD 1"은 / dev / null을 가리 킵니다.
- "command FD 2"는 FD 1이 현재 가리키는 위치 (/ dev / null)를 가리 킵니다.
따라서 "command"의 모든 stdout 및 stderr는 / dev / null로 이동합니다. 파이프에 아무것도 들어 가지 않으므로 "grep"은 화면에 아무것도 표시하지 않고 닫힙니다.
또한 리디렉션 (파일 설명자)은 읽기 전용 (<), 쓰기 전용 (>) 또는 읽기-쓰기 (<>) 일 수 있습니다.
마지막 메모. 프로그램이 FD1 또는 FD2에 무언가를 쓰는지 여부는 전적으로 프로그래머에게 달려 있습니다. 좋은 프로그래밍 관행은 오류 메시지가 FD 2로 이동하고 정상 출력은 FD 1로 이동해야한다고 지시하지만, 두 가지를 혼합하거나 그렇지 않으면 규칙을 무시하는 조잡한 프로그래밍을 종종 발견하게됩니다.
bash를 사용하고 있습니까? 그렇다면:
command >/dev/null |& grep "something"
http://www.gnu.org/software/bash/manual/bashref.html#Pipelines
For those who want to redirect stdout and stderr permanently to files, grep on stderr, but keep the stdout to write messages to a tty:
# save tty-stdout to fd 3
exec 3>&1
# switch stdout and stderr, grep (-v) stderr for nasty messages and append to files
exec 2> >(grep -v "nasty_msg" >> std.err) >> std.out
# goes to the std.out
echo "my first message" >&1
# goes to the std.err
echo "a error message" >&2
# goes nowhere
echo "this nasty_msg won't appear anywhere" >&2
# goes to the tty
echo "a message on the terminal" >&3
This will redirect command1 stderr to command2 stdin, while leaving command1 stdout as is.
exec 3>&1
command1 2>&1 >&3 3>&- | command2 3>&-
exec 3>&-
Taken from LDP
I just came up with a solution for sending stdout
to one command and stderr
to another, using named pipes.
Here goes.
mkfifo stdout-target
mkfifo stderr-target
cat < stdout-target | command-for-stdout &
cat < stderr-target | command-for-stderr &
main-command 1>stdout-target 2>stderr-target
It's probably a good idea to remove the named pipes afterward.
You can use the rc shell.
First install the package (it's less than 1MB).
This an example of how you would discard stdout
and pipe stderr
to grep in rc
:
find /proc/ >[1] /dev/null |[2] grep task
You can do it without leaving Bash:
rc -c 'find /proc/ >[1] /dev/null |[2] grep task'
As you may have noticed, you can specify which file descriptor you want piped by using brackets after the pipe.
Standard file descriptors are numerated as such:
- 0 : Standard input
- 1 : Standard ouptut
- 2 : Standard error
I try follow, find it work as well,
command > /dev/null 2>&1 | grep 'something'
I tend to do things like
composer test &>> /tmp/bob && vim /tmp/bob && rm /tmp/bob
참고URL : https://stackoverflow.com/questions/2342826/how-to-pipe-stderr-and-not-stdout
'developer tip' 카테고리의 다른 글
Java에서 싱글 톤 패턴을 구현하는 효율적인 방법은 무엇입니까? (0) | 2020.09.29 |
---|---|
배열의 모든 멤버를 동일한 값으로 초기화하는 방법은 무엇입니까? (0) | 2020.09.28 |
Android에서 startActivityForResult를 관리하는 방법은 무엇입니까? (0) | 2020.09.28 |
Trello는 사용자의 클립 보드에 어떻게 액세스하나요? (0) | 2020.09.28 |
easy_install보다 pip를 사용하는 이유는 무엇입니까? (0) | 2020.09.28 |