Bash

嵌套時循環不起作用?

  • October 12, 2021

如您所見,我的程式碼很清楚,內部循環似乎可以工作,但是當嵌套在另一個下時,它不起作用,(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 變數傳遞$aawk變數a和將 shell 變數傳遞$b給 awk 變數的方式b。或者,您可以export a b在 shell 中(以便將它們導出到對子程序可見的環境),然後在 awk 中使用ENVIRON["a"]and 。ENVIRON["b"]

input_file如果我對 和變數了解更多ab很可能整個事情都可以在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 循環處理文本被認為是不好的做法?有關詳細資訊和範例。

引用自:https://unix.stackexchange.com/questions/672752