프로그램을 올바르게 시작하고 이후 단계에서 실행 중인 출력(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명명된 파이프를 생성하는 솔루션 을 통해 솔루션을 찾았습니다 .FIFO.
심볼릭 링크를 생성하는 것은 간단하며 쉘에서 허용되는 모든 리디렉션을 사용하는 것이 가능합니다.

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 pid또는 같은 것을 사용해야 kill %1합니다).
두 번째로 내가 그 사람에게 물어볼 때FIFO터미널에 덤프하려면 (다시 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

만약 내가 당신이라면 출력을 파일로 리디렉션하고 출력을 보고 싶을 때 해당 파일을 tailf하세요... 또한 출력이 다소 길어질 것이라고 생각되면 해당 파일의 크기를 제한하고 싶을 수도 있습니다. 또는 출력이 다소 빠를 것이라고 생각하는 경우 디스크 대신 램에 파일을 작성했지만 이러한 작업을 수행하는 방법은 또 다른 질문입니다.

관련 정보