为什么bash中的循环终止后变量值会丢失? [复制]

2023-11-26

我有一个非常简单的 bash 脚本来计算文件每一行出现的数字总和(我知道有更好的方法可以做到这一点,但我实际上需要这个总和作为辅助信息,并且该脚本应该稍后再做一些事情)。脚本如下:

TOTAL=0;
cat $DATAFILE | while read LINE; 
do
      COUNT=`echo $LINE| awk '{print $2;}'`;
      TOTAL=$((TOTAL+COUNT));
done
echo "Total = $TOTAL";

但是,我总是得到输出“Total = 0”。令人惊讶的是,如果我将最后一行移动到 while 循环内,我会得到正确的结果。例如,如果输入文件包含

A 5
B 3
C 6

我得到输出

Total = 5
Total = 8
Total = 14

但当前版本总是输出 0。似乎分配给变量 TOTAL 的值不知何故丢失了。

谁能帮我解决这个问题吗?

提前致谢


This is Bash常见问题解答#24。幸运的是,您只是因为不必要的使用而在这里遇到了问题cat——你根本没有充分的理由使用管道。


当管道完成时,管道的右侧(就像它的其余内容一样,由瞬态子 shell 组成)退出,除非您有shopt -s lastpipe active.

相反,可以添加以下行:

shopt -s lastpipe

或重构你的循环:

while read LINE; 
do
      COUNT=`echo $LINE| awk '{print $2;}'`;
      TOTAL=$((TOTAL+COUNT));
done <"$DATAFILE"

...或者,如果您really需要从另一个进程进行管道传输,请使用进程替换:

while read LINE; 
do
      COUNT=`echo $LINE| awk '{print $2;}'`;
      TOTAL=$((TOTAL+COUNT));
done < <(cat "$DATAFILE")

顺便说一句,如果你的 shebang 是#!/bin/bash, not #!/bin/sh,最好写成如下:

total=0
while read -r _ count do; 
  (( total += count ))
done <"$DATAFILE"

read可以在字符上分割线IFS本身——你不需要使用awk为了那个原因。

按照约定,变量名称应全部小写,除非它们代表环境变量或 shell 内置变量。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么bash中的循环终止后变量值会丢失? [复制] 的相关文章

随机推荐