stdout이나 stderr로 전송되지 않은 출력을 어떻게 캡처합니까?

stdout이나 stderr로 전송되지 않은 출력을 어떻게 캡처합니까?

내가 아는 한, /usr/bin/modulecmd다음 예와 같이 이 명령으로 생성된 일부 출력은 stdout이나 stderr로 전송되지 않습니다.

% /usr/bin/modulecmd bash help null >/dev/null 2>&1
        This module does absolutely nothing.
        It's meant simply as a place holder in your
        dot file initialization.

        Version 3.2.9

모든 출력이 stdout 또는 stderr로 이동하도록 명령(예: /usr/bin/modulecmd)을 호출할 수 있는 방법이 있습니까? 또는 코드에서 /usr/bin/modulecmd캡처를 호출하는 방법이 있습니까?모두일반적으로 터미널로 보내는 출력은 무엇입니까?

답변1

프로그램이 수행하는 작업에 따라 다릅니다. 표준 출력(fd 1) 및 오류(fd 2) 외에도 표준 출력(fd 1)입력하다리디렉션 없이 터미널에서 프로그램이 시작되면 (fd 0)도 일반적으로 읽기 및 쓰기용으로 열리고 출력을 쓰는 데 사용될 수 있습니다. 또 다른 옵션은 /dev/tty프로세스의 제어 터미널에 연결된 새 fd를 제공하는 명시적으로 open 입니다 .

modulecmd어떤 이유로 표준 입력을 사용합니다. 이를 실행하면 strace헤더 라인을 원본 fd 2에 기록한 다음 (fd 0과 관련되지 않은 일부 관련 없는 fd 저글링 후에) fd 0(stdin)을 fd 2에 복사하고 거기에 설명을 인쇄하는 것을 볼 수 있습니다.

...
write(2, "\n--------- 모듈별 Hel"..., 70) = 70
...
[다른 fd의 관련없는 셔플링]
...
반복(0) = 2
write(2, "\t이 모듈은 절대로"..., 37) = 37
쓰기 (2, "\r\n", 2) = 2
write(2, "\t그냥 장소라는 뜻이에요"..., 44) = 44
...

따라서 stdout 및 stderr의 리디렉션 외에도 stdin(fd 0)을 일부 파일로 리디렉션 0>somefile(또는 억제)하여 메시지의 해당 부분을 리디렉션할 수 있습니다./dev/null

유사한 리디렉션을 < /dev/tty통해 프로세스에 명시적인 읽기 전용 fd를 제공하여 출력을 차단할 수도 있습니다. (그러나 프로그램에서는 호출 오류가 발생합니다.) Linux에서는 write()원시 표준 입력이 터미널에 연결된 경우에도 동일한 결과를 얻을 수 있습니다.< /dev/stdin

일부 프로그램을 사용하는 경우 /dev/tty출력을 캡처하는 것이 더 어려울 수 있습니다 . 만약에 뭔가setsid제어 터미널 없이 프로그램을 시작하는 데 사용할 수 있습니다. 이는 열기가 /dev/tty실패함을 의미합니다. (글쎄, Linux에서는 그렇게 됩니다.)

답변2

내 생각에 이 질문에 대한 대답은 "아니요" 이유는 다음과 같습니다. 명령이 시작되기 전에 존재했던 출력만 리디렉션할 수 있습니다. 즉, 명령이 새 출력을 여는 경우 리디렉션을 통해 이를 방지할 수 없습니다.

관련 정보