在shell脚本循环中更改变量

时间:2017-05-13 17:02:59

标签: bash shell

我正在运行一个将警告写入stdout的命令,我希望我的脚本能够停止这些警告,所以拼凑了我在这里学到的很多东西,我有以下内容......

  warnd=false;
  myLongCommand |
    while IFS= read -r line
    do
      if [[ $line == *"WARNING in ."* ]]; then
          warnd=true;
          echo "found a warning!!!!!"
          break
      fi
      echo $line
    done
    echo WARNING IS $warnd
  if [[ "$warnd" == true ]]; then
      echo "exiting due to warning"
      exit
  else
      echo "no warnings"
  fi

但这并不像我期望的那样有效。当myLongCommand发出警告时,我会看到以下回声' d ...

  发现了警告!!!!!

     

警告错误

     

没有警告

为什么在循环后看到的warnd变量没有变化。我已经阅读过关于shell脚本变量的范围,但似乎没有任何迹象表明循环中的变量具有不同的范围。

1 个答案:

答案 0 :(得分:1)

您正在管道中运行命令并修改变量,在管道创建的子shell终止后,不会生效。使用适当的过程替换技术和while循环

while IFS= read -r line
do
  if [[ $line == *"WARNING in ."* ]]; then
      warnd=true;
      echo "found a warning!!!!!"
      break
  fi
done< <(myLongCommand)

值得一读BashFAQ - 024 - I set variables in a loop that's in a pipeline. Why do they disappear after the loop terminates? Or, why can't I pipe data to read?

引用链接页面的简单示例

linecount=0

printf '%s\n' foo bar |
while IFS= read -r line
do
    linecount=$((linecount + 1))
done

echo "total number of lines: $linecount"

理想情况下,lineCount的预期值为2,但由于变量在管道创建的子shell中更新,因此更新不反映子shell退出。

仅供参考,上面的小片段产生了

输出
total number of lines: 0