명령 또는 쉘 스크립트의 출력이 stdout 또는 stderr인지 확인하는 방법


32

명령 또는 셸 스크립트를 실행하면 출력이 나옵니다. 출력 출신 인 경우이 명령이나 쉘 스크립트의 내부를 모른 채, 한 사람이 어떻게 결정합니까 stderrstdout?

예를 들어

$ ls -ld /
drwxrwxr-t  35 root  admin  1258 Dec 11 19:16 /

vs

ls -ld /test
ls: /test: No such file or directory

첫 번째 명령이 인쇄되고 stdout두 번째 명령이 인쇄되었음을 어떻게 확인 stderr합니까?


1
여기서 해결하려는 문제는 무엇입니까?
Kenster

3
누군가가 그런 질문을 할까봐 두려웠습니다. 리디렉션에 대한 나의 이해를 향상시키기를 기대하는 호기심이 많지 않습니다.
KM.

7
당신은 넣을 수 stderred쉘 환경의에서 LD_PRELOAD얻을 수 stdoutstderr다른 색상. 그 정맥에 관련된 질문이 있습니다.
Anko

답변:


18

출력이 이미 인쇄되면 알 수있는 방법이 없습니다. 이 경우, 모두 stdoutstderr, 단자에 연결되어있는 스트림이 이미 텍스트가 터미널에 나타난 시간 손실에 기록 된 대한 정보가 너무; 그들은 터미널로 가기 전에 프로그램에 의해 결합되었습니다.

당신이 할 수있는 일, 위의 같은 경우에 명령을 실행하는 것입니다 stdoutstderr다른 장소로 리디렉션 어떻게되는지. 또는을 stdout리디렉션 한 다음을 /dev/null한 번 stderr리디렉션하고을 한 번 리디렉션 한 /dev/null다음 텍스트가 표시되는 경우를 확인하십시오.

당신은 리디렉션 할 수 있습니다 stdout/dev/null압정으로 고정하여 >/dev/null명령 줄의 끝에, 당신은 리디렉션 할 수 있습니다 stderr/dev/null추가하여 2>/dev/null.


9

을 사용하여 stdout을 > file리디렉션하고을 사용하여 stderr을 리디렉션 할 수 있습니다 2> file. 많은 최신 쉘은 명령으로의 리디렉션을 지원하므로 sed어떤 출력이 어떤 스트림에서 나오는지 강조 할 수 있습니다 .

$ ls 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
1: unity_support_test.0
1: vmwareDnD

$ ls foo 2> >(sed 's/^/2: /') > >(sed 's/^/1: /')
2: ls: cannot access foo: No such file or directory

아주 좋아요! 접두사 대신 색상으로 선을 강조 표시하면 좋을 것입니다.
dotancohen

3
@dotancohen : 하나는 할 수 있습니다! 예 :(echo "this is stdout"; echo "this is stderr" >&2) > >(sed 's/.*/\x1b[32m&\x1b[0m/') 2> >(sed 's/.*/\x1b[31m&\x1b[0m/')
오후

stdout과 stderr의 혼합 출력이 있으면 먼저 stdout이 인쇄 된 다음 stderr이 인쇄됩니다.
nyuszika7 시간

5

annotate-output데비안의에서 스크립트는 devscripts사용자가 선택적으로이 작업을 수행 할 수 있습니다 :

$ annotate-output ls -ld /test
14:54:22 -: Started ls -ld /test
14:54:22 E: ls: cannot access /test: No such file or directory
14:54:22 -: Finished with exitcode 2

두 번째 열은 표준 출력과 표준 에러로 나타냄 OE각각있다.

몇 가지주의 사항이 있습니다. 주요 사항은 다른 답변에서 언급 한 바와 같습니다. 사실 후에는 할 수 없습니다. 쉘이나 터미널은 임의 프로그램이 파일 디스크립터를 사용하는 방법을 알지 못하지만 쉘은 처음에 파일 디스크립터를 설정해야합니다.

이 방법은 fifo를 사용하며, fifo에 쓰는 것은 tty에 쓰는 것과는 다르게 작동 할 수 있으며 두 개의 다른 fifo에 쓰는 것은 확실히 다릅니다 (잠재적 인 타이밍 / 인터리빙 문제). 또한 대화식으로 사용하기에 적합 annotate-output bash하지 않습니다. 예를 들어 훌륭한 계획은 아니지만 많은 다른 목적에 유용합니다. stdin / stdout / stderr 색상 지정에 대한 관련 질문에 대한 답변으로 스크립트 및 셸 함수에 대한 많은 예가 있으며, 가장 강력한 것은 stderrd 로, 대부분의 프로그램의 런타임 수정을 사용하여 stderr에 기록 된 데이터를 수정합니다.

Anko가 링크하는이 질문은 관련 주제에 대한 좋은 대답을 가지고 있습니다 : stdout / stderr 출력 채색 : STDERR과 STDOUT을 다른 색상으로 인쇄하도록 쉘을 구성 할 수 있습니까?


1
루프를 bash사용 while read하고 datestdout 또는 stderr의 각 줄에 대해 하나의 명령을 실행 하는 스크립트 이므로 cmd > >(ts '%T O:') 2> >(ts '%T E:')동등한 것보다 훨씬 덜 효율적 입니다.
Stéphane Chazelas

1

다른 답변과는 별도로 /proc/$PID/fd( 심지어 질문에 대답하지는 않지만) 지적해야합니다 .

$ cat > /dev/null 2> /tmp/blablah &
[1] 3073

[1]+  Stopped                 cat > /dev/null 2> /tmp/blablah
$ ls -l /proc/3073/fd
total 0
lrwx------ 1 kampde kampde 64 Feb 24 11:43 0 -> /dev/pts/33
l-wx------ 1 kampde kampde 64 Feb 24 11:43 1 -> /dev/null
l-wx------ 1 kampde kampde 64 Feb 24 11:43 2 -> /tmp/blablah

보시다시피 여기서 프로세스에 대해 열린 파일 디스크립터를 볼 수 있습니다. 0(가)이며 STDIN, 1입니다 STDOUT2입니다 STDERR. STDOUT 또는 STDERR을 리디렉션하지 않은 경우 /dev/pts/33터미널을 가리 키므로 (이 예제에서는) 최소한 표시됩니다.

참고 : /proc/$PID프로세스 실행에만 존재합니다. 이 경우 cat인수없이 사용 했으므로를 닫을 때까지 끝나지 않습니다 STDIN. 또한 백그라운드에서 실행 했으므로이 예제를 위해 즉시 PID를 갖습니다.


0

무엇을 요구하는지는 분명하지 않지만 도움이 될 수 있습니다.

ls -ld /
echo $?    # Exit status 0 returned because command executed successfully.

ls -ld /test
echo $?    # Non-zero exit status returned -- command failed to execute

출처

종료 코드가 0이면 단순히 명령이 올바르게 (표준 출력)가 실행되는 것을 의미 여기에 종료 코드가 0 (표준 에러)보다 다른 경우 당신은 의미를 찾을 수 있습니다


매우 흥미로운! 종료 상태를 리디렉션과 연결하지 않았습니다. 0은 0이 stdout아닌 0을 의미 stderr합니까?
KM.

7
@KM., 아니오. 나는 그것이 밀접하게 관련되어 있다고 말하지만, 프로그램 stderr이 좋은 오류 코드를 작성하고 좋은 오류 코드를 stdout반환하거나 나쁜 오류 코드를 쓰고 반환하는 것을 막는 것은 아무것도 없습니다 . 실제로, find /root루트로 실행하고 있지 않다고 가정하면, "/ root"가로 인쇄 stdout되고 "find : / root : Permission denied"가로 인쇄됩니다 stderr. 그리고 find는 잘못된 리턴 코드를 리턴합니다.
godlygeek

op의 문제는 stdout 또는 stderr을 나타내는 방법이 분명합니다.
it_is_a_literature

0

일반적으로 STDERR은 프로그램 이름 앞에 메시지가 콜론으로 붙습니다.

예:

rpm -zq some_utils 
rpm: -zq: unknown option

rpm -ql some_utils 
package some_utils is not installed

-1

오류 출력을 캡처하고 테스트하려면 다음을 수행하십시오.

ls -l test 2>errors
if [ -s errors ]; then echo "There were errors:" && cat errors; fi
rm errors
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.