일부 Linux 프로그램의 출력이 STDOUT도 STDERR도 아닌 이유는 무엇입니까?


21

일부 Linux 프로그램의 출력이 STDOUT도 STDERR도 아닌 이유는 무엇입니까?

실제로, 사용하는 '스트림'에 관계없이 모든 프로그램 출력을 안정적으로 캡처하는 방법을 알고 싶습니다. 내가 가진 문제는 일부 프로그램이 출력을 캡처하지 못하는 것입니다.

예를 들어 'time'명령이 있습니다.

time sleep 1 2>&1 > /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

또는

time sleep 1 &> /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

두 번 출력되는 이유는 무엇입니까? 나는 모든 것이 / dev / null 로 파이프 될 것으로 예상했다 .

시간을 사용하는 출력 스트림은 무엇이며 어떻게 파일로 파이프 할 수 있습니까?

이 문제를 해결하는 한 가지 방법은 다음 명령을 포함 하여 Bash 스크립트 를 작성하는 것입니다 combine.sh.

$@ 2>&1

그런 다음 '시간'의 출력을 올바른 방식으로 캡처 할 수 있습니다.

combine.sh time sleep 1 &> /dev/null

(출력이 보이지 않음-올바른)

별도의 결합 스크립트를 사용하지 않고 원하는 것을 달성 할 수있는 방법이 있습니까?


3
먼저이 순서를 반대로한다 : 2>&1 > /dev/null2 지금 (기본적으로, 즉, 단자) (1)이가는 곳으로 간다 "의미하고 1은 현재 진행을을 / dev / null (하지만이 여전히 터미널로 간다!)를 사용합니다. >/dev/null 2>&1말을 "1은 이제 / dev / null로 갔다가 2는 1이가는 곳으로갑니다 (즉, / dev / null로갑니다). 내장 '시간'이 리디렉션되지 않기 때문에 여전히 여기에서 작동하지 않지만 더 일반적으로 정확합니다 (예 : / usr / bin / time을 사용하는 경우 작동 함). "2> & 1"은 2가 1이 아닌 2로 1의 "방향"을 복사하는 것으로 생각하십시오
Olivier Dulac

답변:


38

이 질문은 BashFAQ / 032 에서 다루어집니다 . 귀하의 예에서, 당신은 :

{ time sleep 1; } 2> /dev/null

왜 그런지

time sleep 1 2>/dev/null

그 구문을 사용 time하면 명령을 원할 것입니다 sleep 1 2>/dev/null(예, stderr가 있는 명령이 sleep 1로 리디렉션 됨 ). 내장 은 실제로 가능하도록 그렇게 작동합니다./dev/nulltime

bash 내장은 물론, 그것은 내장이기 때문에 ... 실제로이 작업을 수행 할 수 있습니다. 이러한 동작은 time일반적으로에 위치한 외부 명령 으로 는 불가능합니다 /usr/bin. 과연:

$ /usr/bin/time sleep 1 2>/dev/null
$

자, 질문에 대한 답변

일부 Linux 프로그램의 출력이 STDOUT 또는 STDERR로 이동하지 않는 이유는 무엇입니까?

is : 출력이 stdout 또는 stderr로 이동 합니다.

이것이 도움이되기를 바랍니다!


2
당신은 명시 적으로 그 이동 다른 FD를 작성하고 명령을 할 수 있습니다 (예 : bash는 스크립트 : exec 3>/some/file ; ls >&3 ;)
올리비에 Dulac

@OlivierDulac 물론, 또는 coproc내장으로 더 간단합니다 . 그러나 time내장 의 경우는 아닙니다 .
gniourf_gniourf

@ gniourf-gniourf : 당신의 문장 때문에 "출력은 stdout 또는 stderr로갑니다"^^
Olivier Dulac

14

에 대한 귀하의 특정 질문 time내장 대답했지만, 거기에 있습니다 에 하나 기록하지 않는 일부 명령 stdout또는에가 stderr. 전형적인 예는 Unix 명령 crypt입니다. crypt인수가 없으면 표준 입력을 암호화 stdin하여 표준 출력에 씁니다 stdout. 을 사용하여 사용자에게 암호를 묻는 메시지가 표시 getpass()됩니다 /dev/tty. /dev/tty현재 터미널 장치입니다. 쓰기 /dev/tty는 현재 터미널에 쓰는 효과가 있습니다 (있는 경우 참조 isatty()).

crypt쓸 수없는 이유 stdout는 암호화 된 출력을에 기록하기 때문 stdout입니다. 또한, 더 나은 프롬프트에의 /dev/tty대신 작성하는 stderr사용자 리디렉션 그래서 만약 그 stdoutstderr프롬프트가 여전히 볼 수 있습니다. (같은 이유로 암호화 할 데이터를 읽는 데 사용되므로 crypt에서에서 비밀번호를 읽을 수 없습니다 stdin.)


2
+1. OP와 관련성이 적지 만 "왜 일부 Linux 프로그램의 출력이 STDOUT이나 STDERR로 전달되지 않습니까?" 구글을 통해. :-)
ruakh

0

time sleep 1 > /dev/null 2>&1# "sleep 's"리디렉션은 널을 수행합니다. 그런 다음 "time"은 리디렉션없이 자체 출력을 씁니다. " time (sleep 1 > /dev/null 2>&1)" 와 같습니다 .

(time sleep 1) > /dev/null 2>&1 #는 "time sleep 1"을 실행 한 다음 출력을 null로 리디렉션합니다.

[]에스


-1

귀하의 경우 문제는 리디렉션이 다른 방식으로 작동한다는 것입니다. 당신은 썼다

time sleep 1 2>&1 > /dev/null

표준 출력을 /dev/null리디렉션 한 다음 표준 오류를 표준 출력으로 리디렉션합니다.

모든 출력을 리디렉션하려면 작성해야합니다

time sleep 1 > /dev/null 2>&1 

그런 다음 표준 오류가 표준 출력으로 리디렉션되고 그 후에 표준 오류가 포함 된 모든 표준 출력이로 리디렉션됩니다 /dev/null.


이것은 bash builtin 과는 작동하지 않습니다 time. 몇 가지 설명은 내 답변을 참조하십시오.
gniourf_gniourf

+1이 비슷한 질문에 유용한 답변이기 때문입니다. @Olivier가 위의 질문에 대한 의견에서 더 잘 설명하지만.
윌 셰퍼드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.