シェルスクリプトループで作業ディレクトリを参照する際に問題があります。

シェルスクリプトループで作業ディレクトリを参照する際に問題があります。

各ログファイルを含む複数のディレクトリを含むディレクトリがあります。各ログファイルの名前は、YYYY-MM-DD.logの形式で指定されます。したがって、/path/to/logs/tokyo/2017-06-29.log、/path/to/logs/london/2017-06-29.logなどになります。

毎日の午前0時ごとに新しい日付で新しいログが開き、古いログは再記録されません。

実際、これらのログは数年前にさかのぼり、何千ものものがありますが、テキストファイルだけですが、無視できないほど多くのスペースを占め始めます。だから私がしたいのは、すべてのログディレクトリを見て、今日以前のすべてのログディレクトリを見つけて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コマンドを使用すると、これをよりよく処理できます。しかし、必要なタスクを実行するコマンドが見つかりませんでした。

このスクリプトの最終目標は、ログディレクトリ構造内のすべてのログファイルを見つけ、今日のログではないことを確認し、所定の場所に圧縮してテキストログを削除することです。以前のログを処理するためにただちに1回実行され、毎日午前0時以降に実行されるように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好きなように名前を付けることができます。これにより、アップグレード後に覚えやすくなります。

関連情報