0

ファイルに書き込まれた行を処理する (sh -bourne シェル) スクリプトを作成しようとしています。tail -fの出力をwhile readループにフィードすることで、これを実行しようとしています。この戦術は、Google での私の調査と、同様の問題を扱っているが bash を使用しているこの質問に基づいて、適切なようです。

私が読んだことから、追跡されているファイルが存在しなくなったときに、ループから抜け出すことができるはずです。そうではありません。実際、これを打破できる唯一の方法は、別のセッションでプロセスを強制終了することです。tailこれでテストすると、それ以外の場合は正常に動作しているようです:

タッチファイル
テール -f ファイル | 行を読みながら
行う
  $行をエコー
終わり

別のセッションで追加するデータはfile、上記のループ処理からのファイルに表示されます。

これは HP-UX バージョン B.11.23 にあります。

あなたが提供できる助け/洞察をありがとう!

4

5 に答える 5

1

抜け出したい場合は、ファイルが存在しなくなったら、次のようにします。

 test -f file || break

これをループに配置すると、発生するはずです。

残りの問題は、これがブロックしているため、読み取り行をどのように分割するかです。

これは、 read -t 5 line のようにタイムアウトを適用することで実行できます。その後、5 秒ごとに読み取りが返され、ファイルが存在しなくなった場合にループが中断されます。注意: ケースを処理できるループを作成し、読み取りはタイムアウトしますが、ファイルはまだ存在します。

編集: タイムアウトで読み取りが false を返すように見えるので、テストをタイムアウトと組み合わせることができます。結果は次のようになります。

  tail -f test.file | while read -t 3 line || test -f test.file; do 
          some stuff with $line
  done
于 2008-12-04T06:10:42.283 に答える
0

次のアプローチは、tail -f fileコマンドをバックグラウンドで処理し、プロセスIDとカスタム文字列プレフィックス(ここ tailpid: )をwhileループにエコーします。このループでは、カスタム文字列プレフィックスを含む行が別の(バックグラウンド)ループをトリガーwhileし、5秒ごとにfileまだ存在するかどうかを確認します。そうでない場合は、強制終了され、バックグラウンドループtail -f fileを含むサブシェルが終了します。while

# cf. "The Heirloom Bourne Shell",
# http://heirloom.sourceforge.net/sh.html,
# http://sourceforge.net/projects/heirloom/files/heirloom-sh/ and
# http://freecode.com/projects/bournesh

/usr/local/bin/bournesh -c '
touch file
(tail -f file & echo "tailpid: ${!}" ) | while IFS="" read -r line
do
   case "$line" in
      tailpid:*) while sleep 5; do 
                       #echo hello; 
                       if [ ! -f file ]; then
                          IFS=" "; set -- ${line}
                          kill -HUP "$2"
                          exit
                       fi
                 done & 
                 continue ;;
   esac
   echo "$line"
done
echo exiting ...
'
于 2013-02-23T16:15:59.760 に答える
0

HP-UXについてはわかりませんtailが、GNUtailには--follow=name、ファイルを名前で追跡するオプションがあります(ファイルがリンク解除されているかどうかを検出しない同じファイル記述子から読み取る代わりに、数秒ごとにファイルを再度開きます)。ファイルを開くために使用されたファイル名がリンク解除されると終了します。

tail --follow=name test.txt
于 2008-12-04T04:33:09.347 に答える
0

私はこの答えに満足したことはありませんが、代替案も見つかりませんでした。

kill $(ps -o pid,cmd --no-headers --ppid $$ | grep tail | awk '{print $1}')

現在のプロセスの子であるすべてのプロセスを取得し、テールを探し、最初の列(テールのpid)を印刷して、それを強制終了します。罪を狂わせる-醜い、確かに、それは人生です。

于 2009-02-27T22:39:38.263 に答える
0

GNU tailを使用していない限り、ファイルをフォローするときに自然に終了する方法はありません。-f オプションは、実際にはインタラクティブな監視のみを目的としています。実際、私は、-f が「シェル スクリプトで使用される可能性は低い」と述べている本を持っています。

しかし、問題の解決策として、これが過度に設計された方法ではないかどうかは完全にはわかりませんが、テールをFIFOに送信してから、ファイルをチェックする関数またはスクリプトを用意できると考えましたリンクが解除されていた場合、存在し、尻尾から殺されました。

#!/ビン/sh

センチネル ()
{
    真実でありながら
    行う
        もしも [ !-e $1 ]
        それから
            $2を殺す
            rm /tmp/$1
            壊す
        フィ
    終わり
}       

$1に触れる

mkfifo /tmp/$1

テール -f $1 >/tmp/$1 &

センチネル $1 $! &

猫 /tmp/$1 | 行を読みながら
行う
    $行をエコー
終わり

いくつかの素朴なテストを行いましたが、問題なく動作しているようで、ゴミが横たわっていません。

于 2008-12-10T01:51:48.900 に答える