Linux 시스템의 전원이 켜질 때마다 실행되는 bash 스크립트가 있습니다. 나는 다음과 같이 시작합니다.
( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &
시작한 후 내 창에서 tee 명령을 볼 수 있습니다.메모출력은 아래와 같습니다.
$ ps | grep tee
418 root 0:02 tee /tmp/nginx/debug_log.log
3557 root 0:00 grep tee
로그 크기를 모니터링하는 기능이 있습니다티산란하고 죽인다티로그가 특정 크기에 도달하면 다음 명령을 실행합니다.
monitor_debug_log_size() {
## Monitor the file size of the debug log to make sure it does not get too big
while true; do
cecho r "CHECKING DEBUG LOG SIZE... "
debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
if [ $((debugLogSizeBytes)) -gt 100000 ]; then
cecho r "DEBUG LOG HAS GROWN TO LARGE... "
sleep 3
#rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
kill -9 `pgrep -f tee`
fi
sleep 30
done
}
놀랍게도 살해당함티명령은 start.sh 인스턴스를 통해서도 종료됩니다. 왜 이런거야? 어떻게 끝낼 수 있어?티명령을 실행했는데 start.sh가 계속 실행되나요? 감사해요.
답변1
종료 되면 tee
주어진 명령은 더 많은 출력 쓰기를 시도할 때까지 계속 실행됩니다. 그런 다음 판독기가 없는 파이프에 쓰기를 시도하면 SIGPIPE(대부분의 시스템에서 13개)를 수신합니다.
SIGPIPE를 포착하도록 스크립트를 수정하고 적절한 조치(예: 출력 쓰기 중지)를 취하면 티가 종료된 후에도 계속할 수 있습니다.
죽이는 것보다 낫다tee
그래도,logrotate
단순화를 위해 options 와 함께 사용됩니다 copytruncate
.
견적으로 이동logrotate(8)
:
copytruncate
이전 로그 파일을 이동하고 새 로그 파일을 생성하도록 선택하는 대신 복사본을 생성한 후 원본 로그 파일을 자릅니다. 일부 프로그램에서 로그 파일을 닫으라고 지시할 수 없어 이전 로그 파일에 영원히 계속해서 쓸(추가) 수 있는 경우에 사용할 수 있습니다. 파일 복사와 자르기 사이의 시간 간격은 매우 짧으므로 일부 로깅 데이터가 손실될 수 있습니다. 이 옵션을 사용하면 이전 로그 파일이 그대로 유지되므로 만들기 옵션이 적용되지 않습니다.
답변2
이유를 설명해라"
간단히 말해서: 쓰기가 실패하는 경우아니요프로그램이 종료되고 (기본적으로) 혼란스러워집니다. 생각해 보십시오 . 필요한 10개 행을 가져와서 계속 진행한 후에 하드 드라이브의 나머지 부분을 검색하면서 계속 실행하고 find . | head -n 10
싶지는 않을 것입니다 .find
head
더 나은 방법: 레코더 내부 회전
tee
전혀 사용되지 않는 다음 예를 고려하십시오 .
#!/usr/bin/env bash
file=${1:-debug.log} # filename as 1st argument
max_size=${2:-100000} # max size as 2nd argument
size=$(stat --format=%s -- "$file") || exit # Use GNU stat to retrieve size
exec >>"$file" # Open file for append
while IFS= read -r line; do # read a line from stdin
size=$(( size + ${#line} + 1 )) # add line's length + 1 to our counter
if (( size > max_size )); then # and if it exceeds our maximum...
mv -- "$file" "$file.old" # ...rename the file away...
exec >"$file" # ...and reopen a new file as stdout
size=0 # ...resetting our size counter
fi
printf '%s\n' "$line" # regardless, append to our current stdout
done
다음과 같이 실행하는 경우:
/mnt/apps/start.sh 2>&1 | above-script /tmp/nginx/debug_log
...파일을 추가하는 것으로 시작하고 내용이 100KB를 초과하면 /tmp/nginx/debug_log
파일 이름을 바꿉니다 . /tmp/nginx/debug_log.old
로거 자체가 회전을 수행하므로 회전이 발생하는 동안 파이프 손상, 오류 및 데이터 손실 창이 없습니다. 모든 라인은 한 파일 또는 다른 파일에 기록됩니다.
물론 이를 네이티브 bash에서 구현하는 것은 비효율적이지만 위의 내용은 예시입니다.위의 논리를 구현할 수 있는 프로그램이 많이 있습니다. 고려하다: