在 while 循环中计数

Counting in a while loop

我 运行 正在目录中查找以对文件执行某些操作。我也想统计有多少文件受到影响,但是循环中发生了一些奇怪的事情:

COUNTER=0

find . -type f -name "*.txt" | while read f
do 
  let COUNTER++
  echo Counter is $COUNTER # This shows COUNTER working...
done

echo Counter is $COUNTER # COUNTER is back to 0 at this point...

为什么 $COUNTER 会自行重置?

更改为:

COUNTER=0

while read -r entry
do 
  let COUNTER++
  echo Counter is $COUNTER # This shows COUNTER working...
done < <(find . -type f -name "*.txt")

在循环内部创建了一个新的 SubShell,它具有与外部世界不同的上下文。已经提到的 page 很好地总结了这一点。 @arco444 的另一个答案显示了此页面中的进程替换 解决方法。

与评论相关的页面引用:

BourneShell creates a subshell when the input or output of anything (loops, case etc..) but a simple command is redirected, either by using a pipeline or by a redirection operator ('<', '>').

所以问题不在循环,而是管道(|)运算符的使用。

这也有效:

COUNTER=0

for line in $(find . -type f -name "*.txt");
do
  let COUNTER++
  echo Counter is $COUNTER
done