0

編集 - 明確にするために、4 月 7 日に質問を少し修正しました。

現在の動作環境はOSX 10.4.11です。

特定のフレーズのログ ファイルをスキャンしたいと考えています。スクリプトの開始時にログ ファイルを空にすることはできません。したがって、スクリプトはログへの変更のみをスキャンする必要があります。

私の現在のスクリプト:

#!/bin/sh
  tail -f log.txt | while read line 
do
  if echo $line | grep -q 'LOL CANDY'; then
    echo 'LOL MATCH FOUND'
    exit 0
  fi
done

「LOL CANDY」を見つけた直後に「LOL MATCH FOUND」という点では適切に動作しますが、「LOL CANDY」の後にログに別の追加が行われるまで、実際にはスクリプトを終了しません。すぐに辞める必要があります。特に関係があるかどうかはわかりませんが、「tail -f」が永遠に開いたままになるという問題があります。誰かが tail -f を使用せずに動作する例を教えてもらえますか?

OSXはsh、bash、およびその他のシェルを処理できるため、必要に応じてbashスクリプトを提供してください。

4

6 に答える 6

2

スクリプトを 2 回目に起動するときに、log.txt をクリアしていますか? 実際には 1 回しかかからないのに、2 回の終了ラインが必要だと解釈している可能性があります。-f を使用しているため、スクリプトを起動すると、追加されたもののみが一覧表示されます。

したがって、最初にテールを付けると、必要なラインが得られ、終了します。スクリプトを再起動すると、末尾の -f 引数に入力されないため、最初のインスタンスは無視されます。ただし、次のオカレンスは中止する必要があります。ログを調べると、2 つの LOL CANDY 行が表示されます。これは、末尾をたどっているだけで、ログに既にあるものを見ていないためです。

その行がログに表示されるたびにスクリプトを終了させたい場合は、これをスクリプトの先頭に追加できます。

 #!/bin/sh
  if grep 'LOL CANDY' log.txt; then
   echo 'LOL MATCH FOUND'
   exit 0
  fi

  tail -f log.txt | while read line 
do
  if echo $line | grep -q 'LOL CANDY'; then
    echo 'LOL MATCH FOUND'
    exit 0
  fi
done

また、テール -f を取り除きたい場合は、最初の例でリストしたことを無限の while ループで実行できます (構文が間違っている可能性があります。しばらく時間がかかります)。

#!/bin/sh
while (1)
do
  if grep 'LOL CANDY' log.txt; then
   echo 'LOL MATCH FOUND'
   exit 0
  fi
done

もちろん、ログ ファイルが非常に大きくなると、多くのリソースが消費され、多くの時間がかかります。

于 2010-04-06T20:32:20.410 に答える
1

たぶん、このスクリプトはあなたを助けるでしょう:

#!/bin/bash

FILE=/tmp/mytest
PIPE=/tmp/myfifo

if [[ ! -p $PIPE ]];
then
        mkfifo $PIPE
fi

tail -n 0 -f $FILE >> $PIPE &
TAILPID=$!

while read line < $PIPE
do
        echo "Received: $line"
        if [ "x$(echo "$line" | grep -l -P "asdf")" != "x" ];
        then
                echo "MATCHES"
                kill -TERM $TAILPID
        fi
done;
于 2012-04-27T17:00:46.443 に答える
0

これを試して

(tail -f  file| awk '/interesting/{print;exit}')
于 2010-04-07T02:49:22.067 に答える
0

あなたの質問を理解できるかどうかはよくわかりません。とにかく、私はあなたのスクリプトを試しました、それは最初の実行で終了しませんでした。だから、追加してみませんか:

pid=`ps -ef | grep "tail -f log.txt" | grep -v grep | awk '{print $2}'`
kill -2 $pid

出口が出る前exit 0tail -f

于 2010-04-07T02:54:49.250 に答える
0

私はこれを探していて、次の作品を見つけました(とにかく私のアプリケーションのために):

tail -n 1 -f /var/log/vmkernel.log | grep -m 1 IOMMUIntel >>/var/log/vmkernel.log

ログを追跡し、テキストをgrep見つけ、テキストをログにgrep書き戻します。これにより が終了tailし、プロンプトに戻ります。

具体的には、VM が VMware ESXi で起動するときに、パススルー ビデオ カードがいつアクティブになるかをテストします。

完全なプロジェクトはここにあります。

于 2015-02-21T03:07:40.383 に答える
0
tail -f log.txt | sed -n '/interesting/{
p
q
}'

基本的に、何も出力せずに行を読み取ります。興味深いものを見つけたら、その行を印刷して終了します。

ああ、'tail -f' は必要ないようですね。奇妙なことに、次にパイプに書き込む必要があるときに終了する必要があります。パイプに再度書き込みを行わない場合は、問題になる可能性があります。

私はあなたができると思います:

tail -f log.txt | sed -n '/interesting/{
p
q
}'
echo "EOF" >> log.txt

これにより、エコーする何かが得られるため、試行して失敗し、終了します。

于 2010-04-06T20:05:20.733 に答える