嵌套時循環不起作用?
如您所見,我的程式碼很清楚,內部循環似乎可以工作,但是當嵌套在另一個下時,它不起作用,(
no idea why
)構想是
a
b
用while1迭代變數,交給while2,while2等待log_file中出現一行,等待case語句執行。它不適用於實際過程,它是真正的 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
不會回顯到文件中。
您的腳本有幾個問題,首先
tail -n0 -f $bi_log
是 永遠不會退出,因此外循環永遠不會到達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
管道和 shell while 循環移動到下一行input_file
(並啟動一個新的tail | awk
管道)。順便說一句,這
-v a="$a" -v b="$b"
就是您將 shell 變數傳遞$a
給awk變數a
和將 shell 變數傳遞$b
給 awk 變數的方式b
。或者,您可以export a b
在 shell 中(以便將它們導出到對子程序可見的環境),然後在 awk 中使用ENVIRON["a"]
and 。ENVIRON["b"]
input_file
如果我對 和變數了解更多a
,b
很可能整個事情都可以在awk
. 或perl
。或者,您可以使用
bash
和來完成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
該選項告訴 grep 在匹配
-m NUM
後退出(在這種情況下,NUM=1)。NUM
該-q
選項告訴 grep 保持安靜,即不產生任何輸出,只返回一個退出程式碼(0 表示成功,1 表示失敗……但因為 grep 的輸入來自tail -f
它,它將一直讀取直到找到匹配項)。PS:作為一般的經驗法則,如果你發現自己在 shell 中編寫了一個 while/read 循環,你應該停下來思考“我可能應該在 awk/perl/python/anything-but-shell 中這樣做”。然後用更合適的語言寫出來。
Shell 非常適合協調文本和數據處理工具的執行。處理本身很糟糕。
請參閱為什麼使用 shell 循環處理文本被認為是不好的做法?有關詳細資訊和範例。