
실행 중인 프로세스의 로그 파일이 실수로 삭제되었습니다 python something.py 2>&1 | tee .log
. 스크립트는 zsh의 tmux 창에서 실행 중입니다. 프로세스가 계속 실행 중이지만 로깅되지는 않습니다. 출력 자체가 tmux-scrollback-buffer를 오버플로합니다. 프로세스를 다시 시작하지 않고 어떻게든(관리자/Sudo 권한) 로깅 프로세스를 다시 시작할 수 있습니까?
일반적으로 내 시도는 문제 없이 작동하며 코드는 안전이나 모든 종류의 생산과 관련이 없으며 단순히 복잡한 수학적 계산에 불과합니다. 그러므로 이 시도는 항상 충분했습니다.
현재 상황에서는 프로세스를 다시 시작하지 않고 다시 로깅을 시작할 수 있다면 좋을 것 같습니다.
답변1
프로세스가 열린 파일 설명자를 보유하고 있는 한 파일은 계속 존재하며 tee
모든 것이 여전히 거기에 기록됩니다. /proc를 통해 현재 내용을 복사하여 복구할 수 있습니다.
'tee' 프로세스의 PID를 찾으세요.
열려 있는 파일에 해당하는 파일 설명자 번호를 찾으려면
lsfd -p <PID>
또는lsof -p <PID>
또는 를 사용하십시오 .ls -l /proc/<PID>/fd
(파일명 옆에 "(삭제됨)"이라고 표시되기도 합니다.)'tee'와 같은 간단한 프로그램을 사용하면 처음 열리는 파일은 거의 항상 FD #3이므로 이 게시물의 모든 예제
3
도 마찬가지로 사용됩니다.다음을 통해 파일 내용을 새 파일에 복사합니다
/proc
.cp /proc/<TEE_PID>/fd/3 old.log
(/proc/PID/fd의 심볼릭 링크는 특별합니다. 심볼릭 링크가 깨진 것처럼 보이거나 실제 파일이 아닌 것을 가리키는 경우에도 심볼릭 링크를 열면 여전히 올바른 파일로 확인됩니다.)
'tee'가 새 파일에 쓰기를 시작하도록 하는 것도 가능합니다:
gdb
디버거를 프로세스에 연결합니다 .$ sudo gdb -p <TEE_PID>
그러면 '티'가 일시중지됩니다. 파이프 버퍼를 채울 만큼 충분한 로그 출력을 생성하는 경우 Python 프로그램이 일시 중지될 수도 있습니다(그렇지 않으면 알아차리지 못합니다).
아직 복구하지 않았다면 /proc 트릭을 사용하여 이전 로그 파일을 복구하십시오(gdb 내에서가 아닌 다른 쉘을 통해):
$ cp /proc/<TEE_PID>/fd/3 old.log
이렇게 함으로써~ 후에gdb가 연결되어 있으면(즉, 'tee'가 일시 중지된 동안) 'cp'와 open() 사이의 간격 동안 메시지 손실을 방지할 수 있습니다.
이제 gdb를 사용하여 'tee'를 닫고 파일을 다시 엽니다.
(gdb) p (int) close(3) $1 = 0 (gdb) p (int) open("new.log", 01|0100|02000, 0666) $2 = 3 (gdb) q Detach? y
(값은 다음
01|0100|02000
과 같습니다 .O_WRONLY|O_CREAT|O_APPEND
fcntl.h, 이는 open() 호출이>>
쉘 연산자처럼 동작하게 만듭니다.)'tee'와 같은 간단한 경우에는 open()이 원본 #3 이외의 다른 파일 설명자를 제공할 가능성이 거의 없습니다. 왜냐하면 이것이 가장 낮은 무료 FD이기 때문입니다. 그러나 더 복잡한 프로그램이 있는 일부 상황에서는(번호 지정 간격이 있는 경우) 새로 열린 파일을 호출
dup2($2, 3)
하고close($2)
수동으로 원하는 FD로 이동해야 할 수도 있습니다.이전 파일은 이제 완전히 사라집니다(제거됨에 따라).그리고마지막 파일 핸들이 닫혔습니다.) 'tee'는 아무것도 눈치 채지 못한 채 새 파일에 쓰게 됩니다.
참고: 새 파일을 여는 대신5월아무것도 중단하지 않고 원본 로그 파일을 존재하게 하는 데 사용할 수 있지만 linkat()
아직 테스트하지는 않았습니다. (편집: 불행하게도 linkat() 문서에 따르면 이는 특히 완전히 링크가 해제된 파일에는 작동하지 않습니다.)