쉘 스크립트 루프에서 작업 디렉토리를 참조하는 데 문제가 있습니다.

쉘 스크립트 루프에서 작업 디렉토리를 참조하는 데 문제가 있습니다.

각각 로그 파일이 포함된 여러 디렉터리가 포함된 디렉터리가 있습니다. 각 로그 파일의 이름은 YYYY-MM-DD.log 형식으로 지정됩니다. 따라서 /path/to/logs/tokyo/2017-06-29.log, /path/to/logs/london/2017-06-29.log 등이 됩니다.

매일 자정마다 새 날짜로 새 로그가 열리고 이전 로그는 다시 기록되지 않습니다.

실제로 이러한 로그는 수년 전으로 거슬러 올라가 수천 개가 있으며, 비록 텍스트 파일일 뿐이지만 무시할 수 없을 만큼 많은 공간을 차지하기 시작합니다. 그래서 제가 하고 싶은 것은 모든 로그 디렉터리를 살펴보고 오늘 이전의 모든 로그 디렉터리를 찾아서 bzip으로 압축하는 스크립트를 작성하는 것입니다. 이것이 내가 지금까지 가지고 있는 것입니다:

#!/bin/sh
LOGDATE=$(date +%Y-%m-%d)
LOGPATH="/path/to/logs"

for i in $(ls $LOGPATH/*/*.log); do
    if [ "$i" != "$LOGDATE.log" ];then
        tar cfjv $i.tar.bz2 $i
        rm $i
    else
    fi
done

두 가지 문제에 직면했습니다. 첫째, for 루프의 $(ls ...)가 잘못되었습니다. 이는 매개변수 목록이 너무 길다는 것을 나타냅니다. 둘째, tar 문에서 bzip으로 압축된 출력 파일이 로그 파일과 동일한 디렉토리에 있을 것으로 예상했지만 스크립트가 실행되는 디렉토리에 배치된 것 같아서 이를 만들 수 있는 방법을 찾을 수 없습니다. 루프 사용 올바른 디렉토리.

아마도 잘 작성된 find 및 xargs 명령을 사용하면 이 작업을 더 잘 처리할 수 있을 것입니다. 그러나 필요한 작업을 수행하는 명령을 찾지 못했습니다.

이 스크립트의 최종 목표는 로그 디렉터리 구조에서 모든 로그 파일을 찾아 오늘의 로그가 아닌지 확인하고 제자리에 압축한 후 텍스트 로그를 삭제하는 것입니다. 이전 로그를 처리하기 위해 즉시 한 번 실행된 다음 매일 자정 이후에 실행되도록 crontab에 추가됩니다.

스크립트를 수정하려면 어떻게 해야 합니까? 아니면 더 좋은 방법이 있나요?

유일한 실제 제한은 freebsd 서버이므로 sh 또는 csh를 사용해야 하고 freebsd 도구를 사용해야 한다는 것입니다(예를 들어 더 넓은 범위의 옵션이 있는 GNU find 대신 bsd의 find를 의미함).

답변1

find단일 파일만 압축하는 경우에는 타르볼을 만들 필요가 없다는 사실로 인해 프로세스가 훨씬 간단해집니다.

find $LOGPATH/ -name \*.log -mtime 1 -execdir bzip2 "{}" \;

find가 없으면 특정 마지막 수정 시간(예: "오늘 자정")이 포함된 파일을 생성한 후 다음을 사용하여 -mtime가짜로 만들 수 있습니다 .touch$DATEFILE

find $LOGPATH/ -name \*.log -not -newer /path/to/$DATEFILE -execdir bzip2 "{}" \;
rm /path/to/"$DATEFILE"

답변2

물론 가장 쉬운 방법은 FreeBSD의 기존 도구인 newsyslog.

파일 을 생성 /etc/newsyslog.conf하거나 기존 파일을 편집합니다. 파일 이름(디렉토리에 따라 여러 줄이 필요할 수 있지만 와일드카드를 사용할 수 있음), 보관할 복사본 수(귀하의 경우 매우 큰 수), 파일을 롤할 시기(플래그를 사용할 수 있음)를 지정합니다. 이 작업은 사용자가 직접 수행), 사용하려는 압축 시스템 등

첫 시작을 위해 newsyslog -FvC path-to-your-log-file.

그런데 관련 줄을 에 넣고
/usr/local/etc/newsyslog.conf.d원하는 대로 이름을 지정할 수 있습니다. 이렇게 하면 업그레이드한 후에 기억하기가 더 쉽습니다.

관련 정보