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

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

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

.
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 파일을 정리하지 않습니다.

스크립트를 계속 작동시키면서 이를 수행할 수 있는 방법이 있습니까? 메모; 저는 유닉스 솔라리스를 사용하고 있습니다.

미리 감사드립니다.

답변1

이는 일반적으로 다음을 추가하여 수행됩니다.한숨명령을 다시 시작하는 핸들러다른 명령(일반적으로 logrotate)이 파일을 이동한 후. *nix 운영 체제에서는 파일이 기록되는 동안 파일을 이동할 수 있습니다. (나는 파일이 여전히 동일한 파일 시스템에 있어야 한다고 믿습니다.) 추가 줄은 새 위치의 파일에 추가됩니다.

답변2

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

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

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

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

로그 순환 구성표는 다음과 같아야 합니다.디자인된프로세스에 포함 - 예를 들어 로그 파일을 교체하는 중에 로그 항목이 손실되지 않는 방식으로 로깅을 통합해야 합니다.

(좋아, 그럴 수도 있지가능한stdout실행 중인 프로세스에 대한 / 스트림을 변경하려면 stderr- 하지만 반드시 그래야 하는 일입니다 - 다시 말하지만 -디자인된프로세스에 들어갑니다. bash보내면 자동으로 수행되는 기본 바이너리가 아닙니다 SIGHUP...)

답변3

답변해 주셔서 감사합니다. 방법을 찾을 수 없었습니다. 따라서 해결 방법으로 원래 스크립트를 중지하고 회전을 수행한 다음 사용량이 적을 때 다시 시작하도록 crontab을 설정했습니다.

관련 정보