定期的にパイプラインを表示し、最後のビュー以降に生成された新しい出力を抽出します。

定期的にパイプラインを表示し、最後のビュー以降に生成された新しい出力を抽出します。

パイプの増加出力(例:出力inotifywait)を読み取っています。

定期的にパイプライン出力を確認し、最後に見た後に生成された新しい出力を抽出する必要があります。

シェルスクリプトでこれをどのように実行できますか? Google 検索に使用するキーワードがわかりません。

ベストアンサー1

パイプのデータは一度だけ読み取ることができます。 「新しいコンテンツ」部分は簡単です。 inotifywaitを使用して名前付きパイプを作成し、mkfifo出力をそのパイプにリダイレクト>し、定期的にパイプを読み込みます。

より要求の厳しい部分は、ブロックなしでどこかに書き込むために開く読み取りパイプです。 ddはできます。

これはパイプの作成と継続的な書き込みに使用する設定です。

mkfifo foo
( while true ; do date; sleep 1 ; done ) > foo

未読データをすべて読み込みます。

dd iflag=nonblock if=foo bs=1M count=1 of=buffer.txt

of=...希望の出力ファイルに変更できます。

遅かれ早かれパイプから部分的な行が得られるので、スクリプトがそれを処理できることを確認してください。説明するアクティビティタイプの場合は、バッファが改行で終わるまで追加モードでddを繰り返すことをお勧めします。

buf=buffer.txt
pipe=foo
> $buf # empty the buffer
until [[ $( tail -c1 $buf | od -a ) == *nl* ]] # nl means newline
do
  dd iflag=nonblock oflag=append conv=notrunc if=$pipe bs=1M count=1 of=$buf
  ls -l $buf # see how it grows
  sleep 1 # if the writer dies, this loop will be infinite and we don't want to kill the CPU
done
do_stuff.sh < $buf
# rm $buf

編集:端末でinotifywaitを話し、すべての新しいコンテンツをダンプしたいようです。この方法は簡単です。 whatsnew.shに似たファイルを作成します。

#!/bin/bash
echo "waiting for first output ... "
while true
do
    n=0
    while read -t0.1 line
    do
        echo "[$line]"
        (( n++ ))
    done
    read -p "$n new lines.  Press any key to try again... " -n1 -s </dev/tty
    echo
done

それから始めなさい。

inotifywait | whatsnew.sh

おすすめ記事