【问题标题】:Counting in a while loop [duplicate]在while循环中计数[重复]
【发布时间】:2015-03-21 08:08:25
【问题描述】:

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

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 会自行重置?

【问题讨论】:

标签: linux bash


【解决方案1】:

改为:

COUNTER=0

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

【讨论】:

    【解决方案2】:

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

    与 cmets 相关的页面引用:

    当任何东西(循环、大小写等)的输入或输出但一个简单的命令被重定向时,BourneShell 会创建一个子shell,无论是通过使用管道还是通过重定向运算符('')。

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

    【讨论】:

    • 你知道bash使用SubShell进行while循环的原因吗?
    • 我不太清楚,页面只说在大多数shell中,管道的每个命令都在单独的SubShell中执行。。我的猜测是,这归结为 UNIX 的方式:shell 基本上是互操作的一些单独的程序。
    【解决方案3】:

    这也有效:

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

    【讨论】:

    • $COUNTER 在循环外是 0,不幸的是
    • 可能它依赖于 shell,因为在我的情况下 $COUNTER 外部循环不是 0。我使用 GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
    猜你喜欢
    • 1970-01-01
    • 2018-02-27
    • 2019-07-25
    • 2019-02-01
    • 2014-03-23
    • 1970-01-01
    • 2013-05-21
    • 1970-01-01
    • 2016-06-25
    相关资源
    最近更新 更多