嵌套时循环不起作用?

嵌套时循环不起作用?

正如您所看到的,我下面的代码很清楚,内部循环似乎可以工作,但是当嵌套在另一个循环下时,它就不行了,(no idea why

想法是用a bwhile1 迭代变量并将其交给 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不会回显到文件中。

答案1

您的脚本存在几个问题,首先是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,同时循环移动到下一行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如果我对和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

-m NUM选项告诉 grep 在匹配后退出NUM(在本例中,NUM=1)。该-q选项告诉 grep 保持安静,即不产生任何输出,只返回退出代码(0 表示成功,1 表示失败......但因为 grep 的输入来自tail -f它将永远继续读取,直到找到匹配项)。


PS:作为一般经验法则,如果您发现自己在 shell 中编写 while/read 循环,您应该停下来思考“我应该在 awk/perl/python/anything-but-shell 中执行此操作”。然后用更合适的语言写出来。

Shell 非常适合协调文本和数据处理工具的执行。它本身的处理很糟糕。

为什么使用 shell 循环处理文本被认为是不好的做法?了解详细信息和示例。

相关内容