为什么终止bash中的循环后变量值会丢失? [英] Why variable values are lost after terminating the loop in bash?

查看:138
本文介绍了为什么终止bash中的循环后变量值会丢失?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的bash脚本来计算出现在文件每一行的数字的总和(我知道有更好的方法可以执行此操作,但是我实际上需要将此总和作为辅助信息,并且该脚本应该用于某些操作)稍后).脚本如下:

I have a very simple bash script to compute the sum of numbers appear at each line of a file (I know there are better ways for doing this but I actually need this sum as an auxiliary information and the script is supposed to something more later on). The script is as follows:

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

但是,我总是得到输出"Total = 0".如果我在while循环中移动最后一行,就足够令人惊讶了,我得到了正确的结果.例如,如果输入文件包含

However, I always get the output "Total = 0". Surprisingly enough if I move the last line inside the while loop, I get the correct result. For example if the input file contains

A 5
B 3
C 6

我得到了输出

Total = 5
Total = 8
Total = 14

但是当前版本始终输出0.似乎分配给变量TOTAL的值以某种方式丢失了.

But the current version always outputs 0. It seems the value assigned to the variable TOTAL is somehow lost.

有人可以帮我解决这个问题吗?

Can anyone help me out with the issue?

预先感谢

推荐答案

这是 BashFAQ#24 .幸运的是,由于不必要使用cat,您只在这里单击它-您根本没有充分的理由使用管道.

This is BashFAQ #24. Fortunately, you're only hitting it here because of an unnecessary use of cat -- you have no good reason to have a pipeline in use at all.

完成管道操作后,除非您处于shopt -s lastpipe活动状态,否则管道的右侧(就像其其余内容一样,由瞬态子外壳组成)退出.

The right-hand side of a pipeline (like the rest of its contents, being made up of transient subshells) exits when the pipe is done unless you have shopt -s lastpipe active.

相反,可以添加以下行:

Instead, either add the line:

shopt -s lastpipe

或重组循环:

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

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

...or, in a case where you really need to pipe from another process, use process substitution:

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

顺便说一句,如果您的shebang是#!/bin/bash,而不是#!/bin/sh,则最好编写如下:

By the way, if your shebang is #!/bin/bash, not #!/bin/sh, this would be better written as follows:

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

read可以在IFS本身的字符上分割行-无需为此使用awk.

read can split lines on characters in IFS itself -- you don't need to use awk for that.

按照惯例,除非变量名称代表环境变量或shell内置变量,否则它们应为小写字母.

By convention, variable names should be all-lowercase unless they represent environment variables or shell builtins.

这篇关于为什么终止bash中的循环后变量值会丢失?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆