나는 며칠 동안 스크립트를 실행해 왔습니다. stdout을 stderr로 리디렉션했지만 $HOME/mylog
stderr로 리디렉션하지 않았습니다. 왜냐하면 거기에 아무것도 없을 것이라고 생각했기 때문입니다. 갑자기 stderr에 수천 줄이 나타나기 시작해서 작업을 일시 중지했습니다. $HOME/myerr
스크립트를 다시 시작하지 않고 지금부터 stderr를 리디렉션하는 방법이 있습니까 ?
상자에 대한 sudo 액세스 권한이 있으며 OS X입니다.
dtools를 사용하여 무언가를 캡처할 수 있을까요?
지금까지 스크립트가 수행한 작업을 잃어버리고 처음부터 다시 시작할 수는 없습니다. 디스크의 "메모리에 개체를 덤프"하고, 프로그램을 정지하고, 변수(예: 파일 설명자)를 편집하고다시 덮다새로운 배경으로?
답변1
해당 인터프리터의 프로세스를 gdb에 첨부하면 가능하다고 생각합니다. 나는이 Perl 한 줄 코드로 그것을 시도했습니다
perl -e 'do { print "x\n"; sleep(1) } while(1)'
작동하지만 불행히도 유사한 bash 스크립트에서는 작동하지 않습니다.
먼저, 캡처하려는 출력이 있는 프로세스의 PID를 찾아야 합니다. 그런 다음 다른 터미널에서 시작 gdb
하고 다음 gdb 명령을 실행하십시오.
attach PID
call close(2)
call open("/abs/olu/te/path/filename", 65, 384)
detach PID
그 이후에 기록된 전체 데이터 stderr
는 로 리디렉션됩니다 /abs/olu/te/path/filename
.
attach PID
프로세스를 gdb에 연결하고 중지합니다.call close(2)
stderr
프로세스의 파일 설명자를 닫습니다 (stdout
파일 설명자는 1입니다).call open(...)
새 파일을 열고 새로 생성된 파일 설명자에 대해 사용되지 않은 가장 작은 정수를 가져옵니다.detach PID
과정을 계속하다
적어도 내 컴퓨터에서는 그렇습니다. 처음 두 줄은 POSIX와 호환되지만 세 번째 줄은 그렇지 않습니다.
세 번째 줄의 두 번째와 세 번째 매개변수는 open
에 기록됩니다 man 2 open
. 내 경우 65는 open
파일이 쓰기 전용으로 생성되고 열려야 함을 의미합니다(예: O_WRONLY | O_CREAT
에 정의됨 fcntl.h
). 세 번째 매개변수는 open에게 사용자에 대한 읽기 및 쓰기 권한이 있는 파일 S_IWUSR | S_IRUSR
(에 정의됨 sys/stat.h
)을 생성하도록 지시합니다. 따라서 귀하의 기계에 적합한 값을 직접 파악해야 할 수도 있습니다.
답변2
이것은 대략적인 대답이며 다른 사람들이 더 잘 해주기를 바랍니다. 그러나 다른 아이디어가 없다면 gdb를 연결하고 프로세스가 일부 시스템 호출을 하도록 강제합니다.
(gdb) attach 12345 # target PID
(gdb) p close(2)
(gdb) p open("errfile", O_WRONLY)
(gdb) c