ファイルを観察し、そのファイルの変更に応じてコマンドを実行します。

ファイルを観察し、そのファイルの変更に応じてコマンドを実行します。

特定のファイルにキーワードが表示されたときにコマンドを実行する方法を探していますtemp.txt。たとえば、これまではこれを試しましたtail -F temp.txt | awk '/keyword/ {echo found}'。目的は、echo found含まれている新しい行が追加されたときにのみ実行することです。基本的なコマンドを使って最も簡単な解決策を見つけたいと思います。temp.txtkeyword

このリンクされた投稿の答えは私が望む答えであるようですが、私には効果がなく、その理由も理解できません。

ログに特定のテキストが表示されたときにログに従い、コマンドを実行する最良の方法

ベストアンサー1

努力する:

while :; do awk '/keyword/{print "found"}'; sleep 1; done < temp.txt

または、単に「found」を印刷する代わりにシェルコマンドを実行したい場合:

while :; do awk '/keyword/{system("echo \047found\047"}'; sleep 1; done < temp.txt

強制 POSIX コマンドを使用し、すべての Unix システムのすべてのシェルで動作します。たとえば、

$ echo foo > temp.txt

$ while :; do awk '/keyword/{print "\n>>> found <<<\n"}'; sleep 1; done < temp.txt &
[1] 16520

$ echo keyword >> temp.txt
$
>>> found <<<

バラよりhttps://unix.stackexchange.com/a/629912/133219この方法に関する追加情報。

「キーワード」がファイルに頻繁に表示されず、CPUサイクルを使用してバックグラウンドでループが回転することに興味がある場合は、ループが実行されるたびにスリープ値を最大値に2倍に増やすことで、よりエキゾチックなスリープ値を得ることができます。キーワードが見つからないため、コードは次のbashコードと同様に実行するよりも眠りに時間がかかりますが、すべてのシェルに対して書くことができます。

secs=1
maxSecs=60
while :; do
    if awk '/keyword/{print "found"; f=1} END{exit !f}'; then
        secs=1
    else
        if (( (2*secs) < maxSecs )); then
            secs=$(( 2*secs ))
        else
            secs=$maxSecs
        fi
    fi
    sleep "$secs"
done < temp.txt

「キーワード」がファイルにすばやく表示された場合は、毎秒1回 awkを実行し、それ以外の場合は「キーワード」が再び表示されるまで1分ごとにawkを呼び出すループを繰り返し、1分ごとにもう一度awkを呼び出すします。当然、maxSecsを5、30、3600など好きなように設定してください。

おすすめ記事