以下のコードが明確であることがわかるように、内部ループは機能しているように見えますが、他のループの下に入れ子になっても機能しません。 ( no idea why
)
アイデアは、a
b
while1を使用して変数を繰り返し、それをwhile2に提供することです。 while2 は、 Case ステートメントを実行するために log_file に 1 行が表示されるのを待ちます。
実際のプロセスでは機能しません。実際のlog_fileです。
#!/bin/bash
bi_log='/var/log/process/process.log'
bi_conf='/etc/process/process.conf'
cat input_file | while
read a b
do
while IFS= read -r line; do
case $line in
"Processing Data ended*"* ) echo "Found" &&
echo $a $b >> $bi_conf
;;
esac
sleep 1
break
done < <(tail -n0 -f $bi_log)
done
内部ループが正常に動作しているように見えますが、外部ループの下にネストすると問題が発生する可能性があります。変数a
&b
はファイルに反映されません。
答え1
スクリプトにはいくつかの問題があります。 1つ目はtail -n0 -f $bi_log
終了しないため、外部ループが2行目に達しないことですinput_file
。
次のことをさらに試してください。
while read -r a b ; do
tail -n0 -f "$bi_log" |
awk -v a="$a" -v b="$b" \
'/Processing Data ended/ {
print "found" > /dev/stderr;
print a, b ;
exit
}' >> "$bi_conf"
done < input_file
この awk スクリプトは出力を印刷し、一致するものが見つかるとすぐに終了します。tail -n0 -f
ループが次の行に移動している間、パイプとシェルは終了しますinput_file
(そして新しいtail | awk
パイプが始まります)。
ところで、これが-v a="$a" -v b="$b"
シェル変数を渡すこと$a
です。アッ変数a
とシェル変数は$b
awk変数に変換されますb
。またはexport a b
、シェルでおよびを使用して(子プロセスに表示される環境にエクスポートするために)awkで使用できますENVIRON["a"]
。ENVIRON["b"]
input_file
a
そして変数についてもっと知っていれば、おそらくすべてのことをb
することができますawk
。またはperl
。
または、bash
justとを使用してこれを実行できますgrep
。例えば
while read -r a b ; do
tail -n0 -f "$bi_log" | grep -q -m 1 'Processing Data ended'
echo "Found"
echo "$a $b" >> "$bi_conf"
done < input_file
この-m NUM
オプションは、一致後に終了するようにgrepに指示しますNUM
(この場合はNUM = 1)。この-q
オプションはgrepに静かにするように指示します。つまり、出力を生成せずに終了コードのみを返します(成功の場合は0、失敗の場合は1...しかし、grepの入力は一致するtail -f
ものが見つかるまで永遠に読み続けます)。
PS:一般的にシェルでwhile / readループを書く場合は、それを止めて「これをawk / perl / python / anything-but-shellで行うべきですか?」と考える必要があります。それからもっと適切な言語で書いてください。
シェルは、テキストおよびデータ処理ツールの実行を調整するのに理想的です。ハンドリング自体が不便です。
バラよりシェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?詳細と例をご覧ください。