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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5006229/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:27:21  来源:igfitidea点击:

Why does my Bash counter reset after while loop

bash

提问by S42

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.

我有一个 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

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.htmland other resources.

我不太确定为什么循环后 nKeys 为 0 :( 我认为这是一些基本的东西,但尽管查看http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html我能发现它,但我还是该死的和其他资源。

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

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

回答by Paused until further notice.

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

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

shopt -s lastpipe

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

此外,正如您可能会在 Ignacio 提供的链接中看到的那样,您cat.

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

回答by shivams

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

正如接受的答案中所述,发生这种情况是因为管道产生了单独的子进程。为了避免这种情况,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
}

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

现在它将报告$nKeys“正确”的值(即您希望的)。

回答by ChandraSPola

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