开发者

Why does my Bash counter reset after while loop

I have a Bash script where I want to count how many things were done when looping through a file. The count seems to work within the loop but after it the variable seems reset.

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

The output of the above is something alone the lines of:

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

The output I want is:

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

I am not quite sure why nKeys is 0 after the loop :( I assume it's something basic but damned if I开发者_如何转开发 can spot it despite looking at http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html and other resources.

Fingers crossed someone else can look at it and go "well duh! You have to ..."!


In the just-released Bash 4.2, you can do this to prevent creating a subshell:

shopt -s lastpipe

Also, as you'll probably see at the link Ignacio provided, you have a Useless Use of cat.

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


As mentioned in the accepted answer, this happens because pipes spawn separate subprocesses. To avoid this, command grouping has been the best option for me. That is, doing everything after the pipe in a subshell.

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
}

Now it will report the value of $nKeys "correctly" (i.e. what you wish).


I arrived at the desired result in the following way without using pipes or here documents


#!/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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜