프로그램을 올바르게 시작하고 이후 단계에서 실행 중인 출력(stdout 및 stderr)을 리디렉션할 수 있는 방법은 무엇입니까?

프로그램을 올바르게 시작하고 이후 단계에서 실행 중인 출력(stdout 및 stderr)을 리디렉션할 수 있는 방법은 무엇입니까?

질문은 간단합니다. 잠재적으로 유용하다고 생각했습니다.열기(및 닫기)매 순간 실행 중인 프로그램의 출력이 필요합니다. 보다 정확하게는 표준 출력(및 오류)을 현재 셸에서 다른 셸, /dev/null파일 또는 원래 셸로 자유롭게 리디렉션할 수 있기를 원합니다 .

내가 알고 있는 사실을 활용하여 간단하고 안전한 것을 찾았습니다.미리출력을 켜고 끄겠습니다. 답변도 게시하겠습니다.


아래는 첫 번째 시도입니다. 내가 쉘 번호 35에서 작업한다고 가정해 보겠습니다.

$ who am I                     # the command line to ask where am I
myuser  pts/35  ...            # The answer 

내 시도는 해당 터미널을 가리키는 심볼릭 링크로 시작되었습니다.

ln -s /dev/pts/35  MyOutput  # The command to link

아이디어는 프로그램을 시작하고 해당 링크로 리디렉션을 설정하는 것입니다.

./Execute_program > MyOutput

작동하고 출력을 터미널로 리디렉션하지만 링크를 변경하라는 명령을 실행하면

ln -sf  /dev/null  MyOutput

링크가 바뀌고,하지만 리디렉션은 변경되지 않습니다.내가 바라는 대로. 실행 중인 프로세스에 따라 변경되지 않습니다. 동일한 방식으로 새 프로그램을 시작하면 리디렉션은 링크의 새로운 규칙을 따릅니다.
다시 시작하고 출력 링크를 /dev/null억제하도록 설정하면 예상대로 작동하지만 링크를 다시 변경하면 리디렉션이 변경되지 않습니다.
링크에 링크를 걸어도 같은 결과가 나옵니다. 사용해 hard link도 상황은 바뀌지 않습니다.

슬프게도쉘은 시작 시 명령줄을 확장합니다.

비슷한 방식으로 이를 수행할 수 있습니까? 아니면 링크가 변경된 프로세스(또는 PPID 프로세스)와 통신하는 방법을 찾을 수 있습니까?


노트:

"실행 중인 프로세스의 출력을 어떻게 리디렉션합니까?" 시리즈의 질문이지만 이 시점에서는 시작되지 않습니다."앗, 프로그램을 시작했지만 출력을 리디렉션하는 것을 잊어버렸습니다. 이제 이 작업을 수행하고 싶습니다.", 그러나 반대 관점에서 보면 "나중 단계에서 출력을 다른 곳으로 리디렉션하려는 명시적인 목표를 가지고 프로그램을 어떻게 시작합니까?"입니다.

프로그램의 소스코드를 수정하는 것이 불가능하거나 불편한 경우에는 이런 과정을 이용하려고 합니다.
읽다disown한 화면에서 다른 화면으로 처리, 사용 및 전송 될 수 있습니다 screen. 또는 디버거를 사용하여 프로세스를 가로챌 수 있습니다. 이러한 모든 솔루션은 많은 경험과 노력으로 작동할 수 있지만 일부 솔루션은 특정 비례 위험을 나타냅니다.

답변1

mkfifo명명된 파이프를 생성하여 해결책을 찾았습니다 .선입선출.
이는 심볼릭 링크를 생성하고 쉘이 허용하는 모든 리디렉션을 사용하는 것만큼 간단합니다.

mkfifo MyOutput

ls -l주어진

0 prw-r--r-- 1 My_username My_username  0 May 11 17:45 MyOut|

이 링크로 리디렉션하여 프로그램을 시작할 수 있습니다

./Execute_program > MyOutput  &  cat MyOutput 

출력이 터미널에서 흐르기 시작합니다.

ctrl+를 누르면 프로세스가 중단되지만 실행 중인 프로세스는 중단되지 않습니다( 이 작업을 수행하려면 또는 같은 것을 c사용해야 합니다 ). 두 번째로 물어볼 때kill pidkill %1
선입선출터미널에 덤프(다시 사용 cat MyOutput)하려면 그 순간 출력 덤프가 시작됩니다.

참고 및 경고:

  • 덤프는 내가 요청하지 않을 때까지 모든 출력을 저장합니다 FIFOs.
    처음에 물었더니 그럴까요?씻어모두.
  • 다른 파일로 리디렉션(또는 추가)할 수 있나요?cat MyOutput >> NewRealFile
  • cat MyOutput다른 단말기에서도 사용할 수 있어요!
  • 경고하다: 2개의 다른 프로그램(또는 인스턴스)에 출력을 동일한 FIFOs플럭스로 리디렉션하도록 요청하면 병합됩니다(아니요선험적으로라인이 어느 프로그램에서 왔는지 구별하는 방법).
  • 경고하다: 두 번 이상 요청하면(아마도 다른 터미널에서) 요청당 한 줄씩 제공되어 요청자에게 출력을 분할합니다. 어쩌면 안전한 해결 방법이 있을 수도 있습니다.

답변2

귀하의 질문을 올바르게 이해한 경우:

script 1>>~/out.fifo 2>>~/error.fifo 

그런 다음 모니터링하려면 다음을 수행할 수 있습니다.

watch cat ~/out.fifo

Fifos 대신 실제 파일을 사용할 수 있습니다

script 1>/tmp/$0-out 2>/tmp/$0-error

그런 다음 tail -f를 수행하면 스크립트를 다시 실행할 때 교체됩니다.

나는 두 번째 접근 방식을 선호하거나 멀티플렉서(예: 스크린 또는 이번 주 인기 환생)를 사용하는 것을 선호합니다.

screen -t "name" bash -c 'script'

그 다음에

screen -r

"모니터링"하고 Ctrl+ad를 눌러 분리하세요.

실행 후 출력을 보려면 스크립트 끝에서 일시 중지하세요.

답변3

내가 당신이라면 출력을 파일로 리디렉션한 다음 출력을 보고 싶을 때 해당 파일을 추적할 것입니다... 출력이 상당히 클 것이라고 생각되면 파일 크기를 제한할 수 있습니다. 파일을 디스크보다 메모리에 쓰는 것이 훨씬 더 빠를 것이라고 생각한다면, 그렇게 하는 방법은 또 다른 질문입니다.

관련 정보