inotifywatch
ログファイルの変更を監視するスクリプトを作成しようとしています。特定のメッセージがログファイルに書き込まれたら、特定の機能をトリガーする必要があります。スクリプトは現在、次の基本形式で存在します。
while inotifywait -e modify /var/log/auth.log
do
alert=$(tail -n1 /var/log/auth.log | grep -E -o ".{0,7}password")
if [[ $alert == "Failed password" ]]
then
echo "FAILURE" >> test.log
elif [[ $alert == "cepted password" ]]
then
echo "LOGIN" >> test.log
fi
done
すべてがうまく動作します - 監視対象のログファイルがinotifywatch
表示されるまで回転。その後、動作が停止します。回転中に監視されたファイルの名前が変更され、記録されなくなり、その場所に監視するように求められなかった古い名前inotify
の新しいファイルが作成されたためです。
inotifywatch
usingからusingに切り替えて問題を回避しようとしましたが、tail -f
ここでも同じ問題が適用されるようです。
これで、監視だけでなくファイルの作成も監視し、修正のために監視を再開する巨大なif
構造を作成することでこの問題を解決できることに気づきました。しかし、私は仕事を単純に保つのが好きですが、より簡単な方法があるかどうかを知っていますか? (いいえ、私はFail2banのようなあらかじめ作成されたソリューションを使用したくありません。私にとって興味深いのは、簡単なツールを使用してこのようなものを自分で作成することです。)inotifywatch
modify
ベストアンサー1
inotify
名前ではなく、inodeでディレクトリ内のファイルを監視するために使用されます。ファイルが回転すると、その内容は変更されなくなります(デーモンが新しく作成されたログファイルを使用するように再ロードされるまで短時間を除く)。
AFAIKはtail -f
inotifyシステムを使用しているので役に立ちません。ただし、実行可能なソリューションがある場合、バージョンがこの機能をサポートしている場合はtail -f
tail tail --follow=name
()を使用してください(POSIX tailはサポートしていません)。これにより、filenameで識別されたファイルが監視されます。以下は、マニュアルページから抜粋した内容です。tail -F
tail
tail
--follow(-f) を使用すると、tail はデフォルトでファイル記述子に従います。つまり、tailがあるファイルの名前が変わっても、tailは続行し続けます。このデフォルトの動作は、ファイル記述子(ログの回転など)ではなく、ファイルの実際の名前を実際に追跡したい場合には望ましくありません。この場合は --follow=name を使用してください。これにより、tailは名前の変更、削除、および作成に対応するように名前付きファイルを追跡します。
【書き直す】
使用例:
tail -n0 -F my_file.log \
| while read -r log_line; do
do_something_with "$log_line"
done
パイプによってwhileループが子プロセスで実行されるため、ループ外の変数を変更しようとすると問題が発生する可能性があります。を使用する場合、bash
望ましくない効果はありませんが、読みやすくなる次の代替構文を使用できます。
while read -r log_line; do
do_something_with "$log_line"
done < <(tail -n0 -F my_file.log)