2008-10-30 2 views
39

필자는 실행을 멈추어야 할 스크립트가 있지만 항상 멈춰 있습니다.프로세스가 Linux에서 다른 프로세스의 stdout 및 stderr을 가로 챌 수있는 방법은 무엇입니까?

그들이 stdout과 stderr에 읽을 수있는 방식으로 쓰는 것을 이해할 수있는 방법이 있습니까?

나는
tail -f /proc/(pid)/fd/1 

을 수행하는, 예를 들어, 시도했지만 그건 정말 작동하지 않습니다. 그것은 어쨌든 긴 발사였습니다.

다른 아이디어? strace 자체는 매우 장황하고 읽을 때 읽을 수 없습니다.

참고 : 나는 인데, 그 밖의 어떤 내용이 아닌에만 관심이 있습니다. 나는 내 자신의 다른 것을 알아낼 수있다. 이 질문은을 실행 한 후 실행중인 프로세스의 stdout 및 stderr에 액세스하는 데에만 초점을 둡니다.

+0

[reptyr] (https://github.com/nelhage/reptyr) – Louis

+0

대상 프로그램이 파이프에 쓰고있을 때 – user666412

답변

1

당신은 운영 체제를 명시하지 않는 설명을 읽고,하지만 난 자상을거야 및 "리눅스"라고 말하십시오.

stderr 및 stdout에 기록되는 내용을 보는 것이 도움이되지 않을 수도 있습니다. 유용 할 경우 스크립트를 시작하기 전에 stderr 및 stdout의 복사본을 가져 오기 전에 tee (1)를 사용할 수 있습니다.

ps (1)를 사용하여 wchan를 찾을 수 있습니다. 이것은 프로세스가 무엇을 기다리고 있는지 알려줍니다. strace 출력을 보면 출력의 대부분을 무시하고 마지막 (차단 된) 시스템 호출을 식별 할 수 있습니다. 파일 핸들에 대한 작업 인 경우 출력에서 ​​뒤로 이동하여 기본 객체 (파일, 소켓, 파이프 등)를 식별 할 수 있습니다. 거기에서 대답이 명확해질 수 있습니다.

프로세스를 보내 코어 덤프를 발생시키는 신호를 보낸 다음 디버거와 코어 파일을 사용하여 스택 추적을 얻을 수도 있습니다.

40

나는 Jauco의 대답을 편집 할 수 없으므로 나는 저에게 효과가있는 완전한 대답을 줄 것이다. (Russell의 페이지는 undaredeed 동작에 의존한다. stdout을 위해 fd 1을 닫으면 다음 creat 호출은 fd 1.

그래서,이 같은 간단한 끝없는 스크립트 실행 : PID를 얻기

import time 

while True: 
    print 'test' 
    time.sleep(1) 

그것이 test.py에 저장,

python test.py 

실행을 :

gdb -p (pid) 

을하고 FD 마법을 수행합니다 :

ps auxw | grep test.py 

이제 gdb를 첨부

(gdb) call creat("/tmp/stdout", 0600) 
$1 = 3 
(gdb) call dup2(3, 1) 
$2 = 1 

이제 할 수있는 꼬리/tmp를/표준 출력을 표준 출력으로 이동하는 데 사용되는 출력을 참조하십시오.

+1

dup2 솔루션이 더 좋았지 만 (creat 1을 반환하는 것과 관련하여) 0이 사용되고 다른 누구도 파일 설명자를 작성하지 않는 한 보증하지 않습니다. UNIX는 사용 가능한 가장 낮은 fd 번호가 리턴됨을 보장합니다. – ephemient

+0

이것은 실제로 작동하지 않습니다. 이 모든 명령을 실행할 때까지 유용한 표준 출력이 이미 ether에 손실되었을 수 있으며이 방법은 이미 인쇄 된 것을 소급 적으로 캡처하지 않습니다. – Cerin

8

GDB 방법은 더 나은 것 같다,하지만 당신은 너무, strace를 사용하여이 작업을 수행 할 수

의 strace -p -e 쓰기 = 1 -s 1024 -o 파일이

-e write=set 
       Perform a full hexadecimal and ASCII dump of all the 
       data written to file descriptors listed in the spec- 
       ified set. For example, to see all output activity 
       on file descriptors 3 and 5 use -e write=3,5. Note 
       that this is independent from the normal tracing of 
       the write(2) system call which is controlled by the 
       option -e trace=write. 

이 다소 thanyou을 출력 필요 (16 진수 부분),하지만 당신은 그것을 쉽게 sed 수 있습니다.

2

strace는 -ewrite (및 = 1 접미사가 아님)를 사용하면 훨씬 적은 양을 출력합니다. 그리고 그것은 gdb 메소드보다 약간 간단합니다.

나는 (내가 인코딩 프로세스를 소유하지 않기 때문에 sudo를)을 기존 MythTV 인코딩 작업의 진행 상황을보고 그것을 사용 :

$ ps -aef | grep -i handbrake 
mythtv 25089 25085 99 16:01 ?  00:53:43 /usr/bin/HandBrakeCLI -i /var/lib/mythtv/recordings/1061_20111230122900.mpg -o /var/lib/mythtv/recordings/1061_20111230122900.mp4 -e x264 -b 1500 -E faac -B 256 -R 48 -w 720 
jward 25293 20229 0 16:30 pts/1 00:00:00 grep --color=auto -i handbr 

$ sudo strace -ewrite -p 25089 
Process 25089 attached - interrupt to quit 
write(1, "\rEncoding: task 1 of 1, 70.75 % "..., 73) = 73 
write(1, "\rEncoding: task 1 of 1, 70.76 % "..., 73) = 73 
write(1, "\rEncoding: task 1 of 1, 70.77 % "..., 73) = 73 
write(1, "\rEncoding: task 1 of 1, 70.78 % "..., 73) = 73^C 
3

내가 strace를 사용하고 텍스트를 지우려면 진수 출력을 해제 코드 :

PID=some_process_id 
sudo strace -f -e trace=write -e verbose=none -e write=1,2 -q -p $PID -o "| grep '^ |' | cut -c11-60 | sed -e 's/ //g' | xxd -r -p" 

다른 답변에서이 명령을 결합했습니다.

9

"gdb 메소드"를 마무리하고 몇 가지 추가 기능을 추가하는 몇 가지 새로운 유틸리티가 있습니다. 제가 지금 사용하는 것은 "reperr"("Re-PTY-er")입니다. STDERR/STDOUT을 잡을 수있을뿐만 아니라 프로세스의 제어 터미널을 실제로 변경합니다 (이전에 터미널에 연결되어 있지 않은 경우에도 마찬가지입니다).

이 기능을 사용하는 가장 좋은 방법은 화면 세션을 시작하고 실행중인 프로세스를 화면 내의 터미널에 다시 연결하여 안전하게 분리하여 나중에 다시 돌아올 수 있도록하는 것입니다.

인기있는 배포판에 패키지되어 있습니다 (예 : 'apt-get install reptyr').

http://onethingwell.org/post/2924103615/reptyr

2

당신은 reredirect (https://github.com/jerome-pouiller/reredirect/)를 사용할 수 있습니다.

타입

reredirect -m FILE PID 

출력한다 (표준 오차)가 파일에 기록된다.

reredirect README은 프로세스의 원래 상태를 복원하는 방법, 다른 명령으로 리디렉션하는 방법 또는 stdout 또는 stderr 만 리디렉션하는 방법에 대해서도 설명합니다.

관련 문제