目的

目的

目的

そのため、ログが特定のサイズに達したときにログを記録して回転させるスクリプトを作成しました。意図的にログに反映されたエラーと他のコマンドの出力の両方をキャプチャしたいと思います。

これを達成したのは、STDINとSTDOUTをteeプロセス置換にリダイレクトし、savelogログを回転させる小さな関数を書くことでした。

#!/bin/bash

LOGFILE="/var/log/ps.log"
exec > >(tee "$LOGFILE") 2>&1

LOGPATH="/var/log"
MAX_LOGFILE_SIZE=5
rotateLog() {
        currentsize=$(du -k $LOGFILE | cut -f1)
        if [ $currentsize -ge $MAX_LOGFILE_SIZE ]; then
                savelog -dn $LOGFILE &>/dev/null
        fi
}

while :; do
    echo "A computer program can easily produce gibberish - especially if it has been provided with garbage beforehand. This program does something a little different. It takes a block of text as input and works out the proportion of characters within the text according to a chosen order. For example, an order of 2 means the program looks at pairs of letters, an order of 3 means triplets of letters and so on. The software can regurgitate random text that is controlled by the proportion of characters. The results can be quite surprising."

    rotateLog

    sleep 5
done

質問

問題は、ps.logログが交換された後もps.log.20180829131658すべてのログが記録されps.log.20180829131658続け、次のエラーが発生することです。

du: '/var/log/ps.log' にアクセスできません。そのファイルやディレクトリはありません。/ps.sh:行12:[:-ge:単項演算子が必要です。

その結果、ログはもう循環しません!

仮説

ps.log回転すると、ps.log.20180829131658新しいログファイルが作成されたとします。しかし、一度だけ実行されるps.logので必ずしもそうではありません(execここで正確に何が起こっているのかを説明できる人はいますか?)つまり、スクリプトの先頭にあります。

観察する

>(tee "$LOGFILE")/var/log/p.logまた、その時点で新しいファイル記述子が作成されますp.log.20180829131658!これは明らかにログが記録され続ける結果をもたらしますp.log.20180829131658誰でもこの動作を説明できますか?

root@b537ccc2c1ab:/var/log# ls -lrt
-rw-r--r-- 1 root root   7248 Aug 29 13:16 ps.log

root@b537ccc2c1ab:/var/log# ls -lrt /proc/*/fd
/proc/8979/fd:
total 0
l-wx------ 1 root root 64 Aug 29 13:16 3 -> /var/log/ps.log
lrwx------ 1 root root 64 Aug 29 13:16 2 -> /dev/pts/17
lrwx------ 1 root root 64 Aug 29 13:16 1 -> /dev/pts/17
lr-x------ 1 root root 64 Aug 29 13:16 0 -> pipe:[3889791]


root@b537ccc2c1ab:/var/log# ls -lrt
-rw-r--r-- 1 root root  11098 Aug 29 13:17 ps.log.20180829131658

root@b537ccc2c1ab:/var/log# ls -lrt /proc/*/fd
/proc/8979/fd:
total 0
l-wx------ 1 root root 64 Aug 29 13:16 3 -> /var/log/ps.log.20180829131658
lrwx------ 1 root root 64 Aug 29 13:16 2 -> /dev/pts/17
lrwx------ 1 root root 64 Aug 29 13:16 1 -> /dev/pts/17
lr-x------ 1 root root 64 Aug 29 13:16 0 -> pipe:[3889791]

このログ記録とログ循環スキームを使用してどのように目標を達成できますか?特に、ログの回転に加えて、スクリプトの他のすべてのコマンドからエラーと出力をキャプチャしながら、私のスクリプトが最新のログファイルに書き込むことができる方法は何ですか?

ベストアンサー1

プロセスによってファイルが開かれると、名前の変更、切り取り、削除など、ファイルに対してさまざまな操作を実行できますが、プロセスはまだファイルを開いています。一般的な間違いは、ログファイルがすべてのディスクスペースを使用すると、人々がスペースを解放するためにファイルを削除することです。ただし、ログファイルに書き込むプロセスはまだ開いているため、スペースは解放されません。ファイルに割り当てられたブロックは、プロセスがファイルを閉じたときにのみ解放されます。 (ここで回避策はファイルを切り取ることです。つまり> logfile、.)

あなたの場合、ファイルの名前を変更しましたが、ファイルを作成するプロセスはそれを知らないし、気にしません。

ユーティリティにはこのような場合のオプションlogcheckがありますcopytruncate。つまり、ログファイルを置き換えられた名前にコピーしてから、元のログファイルを切り捨てます。あなたも同じことができます:

rotateLog() {
    currentsize=$(du -k $LOGFILE | cut -f1)
    if [ $currentsize -ge $MAX_LOGFILE_SIZE ]; then
            ROTATEDLOG=$LOGFILE.$(date +%Y%m%d%H%M%S)
            cp -p $LOGFILE $ROTATEDLOG && true > $LOGFILE
    fi
}

より良い方法は、ログファイルのクローズや再オープンなどのSIGHUPシグナルを理解するようにプロセスを変更することです。trapこの問題を処理するには、シェルコマンドを参照してください。

おすすめ記事