为什么我的Bash计数器在while循环后重置

时间:2011-02-15 16:14:50

标签: bash

我有一个Bash脚本,我想要计算在循环文件时完成了多少事情。计数似乎在循环内工作,但在它之后变量似乎重置。

nKeys=0
cat afile | while read -r line
do
  #...do stuff
  let nKeys=nKeys+1
  # this will print 1,2,..., etc as expected
  echo Done entry $nKeys
done
# PROBLEM: this always prints "... 0 keys"
echo Finished writing $destFile, $nKeys keys

以上的输出只有以下内容:

Done entry 1
Done entry 2
Finished writing /blah, 0 keys

我想要的输出是:

Done entry 1
Done entry 2
Finished writing /blah, 2 keys

我不太确定为什么nKeys在循环之后是0 :(我认为这是基本的但是如果我能看到http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html和其他资源我可以发现它该死的。

手指越过别人可以看着它然后“好吧!你必须......”!

3 个答案:

答案 0 :(得分:5)

在刚刚发布的Bash 4.2中,您可以这样做以防止创建子shell:

shopt -s lastpipe

此外,正如您可能会看到Ignacio提供的链接,您有一个Useless Use of cat

while read -r line
do
    ...
done < afile

答案 1 :(得分:2)

正如在接受的答案中所提到的,这是因为管道产生了单独的子进程。为避免这种情况,command grouping对我来说是最好的选择。也就是说,在子shell中管道后执行所有操作。

nKeys=0
cat afile | 
{
  while read -r line
  do
    #...do stuff
    let nKeys=nKeys+1
    # this will print 1,2,..., etc as expected
    echo Done entry $nKeys
  done
  # PROBLEM: this always prints "... 0 keys"
  echo Finished writing $destFile, $nKeys keys
}

现在它会正确报告$nKeys&#34;&#34; (即你想要的)。

答案 2 :(得分:0)

我通过以下方式得到了所需的结果,而没有使用管道或此处的文件


#!/bin/sh
counter=0
string="apple orange mango egg indian"
str_len=${#string}
while [ $str_len -ne 0 ]
do
   c=${string:0:1}
   if  [[ "$c" = [aeiou] ]]
   then
       echo -n "vowel : "
       echo "- $c"
       counter=$(( $counter + 1 ))
   fi
   string=${string:1}
   str_len=${#string}
done
   printf "The number of vowels in the given string are : %s "$counter
   echo