스크립트가 실행되는 동안 리디렉션 경로 변경

스크립트가 실행되는 동안 리디렉션 경로 변경

파일로 리디렉션하는 위치에서 항상 출력을 제공하는 스크립트가 있습니다. 내가 하고 싶은 작업은 리디렉션된 파일을 회전하는 것입니다. 아래는 스크립트를 시작하고 리디렉션하는 위치입니다.

.
somecode
.    
su - username -c "command >> /path/to/directory/output.txt" &
.
.
code continues..

아래는 제가 만들려고 하는 crontab입니다.

cd /path/to/directory/
timestamp=`date "+%Y%m%d"`
mv ./output.txt ./logs/output.txt_$timestamp
touch output.txt
chmod 757 ./output.txt
gzip ./logs/output.txt_$timestamp
find ./logs/output.txt* -type f -mtime +2 | xargs rm

또는 이것도 작업을 수행하지 못합니다.

timestamp=`date "+%Y%m%d"`
cp ./output.txt ./logs/output.txt_$timestamp
echo "" > ./output.txt
gzip ./logs/output.txt_$timestamp

첫 번째 코드에서는 원본 스크립트가 실패하고 더 이상 작동하지 않습니다. 두 번째 스크립트에서는 output.txt 파일을 정리하지 않습니다.

스크립트를 계속 실행하면서 이를 수행할 수 있는 방법이 있습니까? 참고: 저는 Unix Solaris를 실행하고 있습니다.

미리 감사드립니다.

답변1

이는 일반적으로 다음을 추가하여 수행됩니다.한숨을 쉬다명령 처리기 다시 시작다른 명령(보통 logrotate) 후에 파일을 이동합니다. *nix 운영 체제에서는 파일이 작성되는 동안 파일을 이동할 수 있습니다. (내 생각에는 파일이 여전히 동일한 파일 시스템에 있어야 한다는 점에 주의해야 합니다.) 추가 행은 파일의 새 위치에 추가됩니다.

답변2

실제로 실행 중인 프로세스에 대한 리디렉션 stdout및/또는 새 파일을 변경할 수 없습니다(아래 참고 참조). 이는 리디렉션을 사용 하거나 장기 실행 프로세스에 대한 로그 파일로 stderr사용하는 이유 중 하나입니다.stdoutstderr나쁜아이디어. )

프로세스가 시작되면 명령의 리디렉션 요소가 프로세스를 시작한 셸에 의해 실행됩니다. 필요한 경우 대상 파일이 적절한 모드(추가 또는 덮어쓰기)로 열리고 생성되며 리디렉션 모드에 따라 0바이트로 잘릴 수 있습니다. 그런 다음 열린 파일 설명자는 하위 프로세스로 전달됩니다. 말 그대로, 열려 있는 파일 설명자는 하위 프로세스가 리디렉션된 파일에 대해 가지고 있는 유일한 링크입니다. 다음은 파일에 대한 링크입니다.

이것은 중요한 점입니다. 파일에 대한 직접 링크이기 때문에 열린 설명자는 파일의 디렉토리 항목인 "파일 이름"과 동일합니다. 해당 이름을 변경하거나 해당 디렉토리 항목을 삭제하는 것(예: rm명령 사용)은 프로세스에서 열려 있는 파일 설명자에 전혀 영향을 미치지 않습니다.

@l0b0의 대답은 정확합니다. 로그를 회전해야 하는 프로세스는 SIGHUP핸들러를 사용하여 이러한 회전을 수행하는 경향이 있지만 리디렉션된 출력의 경우 "로그 회전"은 그렇게 간단하지 않습니다. 새 출력 파일의 이름은 무엇입니까? 하위 프로세스는 자신의 "이름"이 무엇인지 stdout또는 무엇인지 전혀 모릅니다 stderr. 출력 "파일"은 파일이 아닐 수도 있습니다.

로그 순환 구성표는 다음과 같아야 합니다.디자인됨프로세스에 - 예를 들어 로그 파일을 회전하는 동안 로그 항목이 손실되지 않는 방식으로 로깅이 통합되어야 합니다.

(알았어 그럴수도 있지가능한실행 중인 프로세스의 stdout/ 스트림을 변경합니다 stderr. 하지만 이는 필수입니다.디자인됨프로세스에 들어갑니다. bash보내면 바로 사용할 수 있는 바이너리가 아닙니다 SIGHUP...)

답변3

모든 사람의 답변에 감사드립니다. 이 작업을 수행할 방법을 찾을 수 없었습니다. 따라서 해결 방법으로 원본 스크립트를 중지하고 회전한 후 사용량이 적은 시간에 다시 시작하도록 crontab을 설정했습니다.

관련 정보