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