我在 Bash 中使用 while+pipe 的全局变量有什么问题?



我正在尝试观察并输出较长脚本的进度。(稍后我想使用进度来计算进度条(。

下面是一个缩短的示例:

#!/bin/bash
PROGRESS=0
updateprogress () {
PROGRESS=$((PROGRESS + 1))
echo $PROGRESS
}
<do something>
updateprogress
sudo cat /root/.virtualMachines | while read -r name ipAddr        # <-7 lines 
do
<do something>
updateprogress
done
sudo cat /root/.virtualServices | while read -r name ipAddr        # <-3 lines
do
<do something>
updateprogress
done

我现在期望的将是这样的输出

1    <-# before the first while)
2
3
4
5
6
7
8    <-# end of first while)
9
10
11   <-# end of second while)

但我得到的是

1    <-# before first while)
2
3
4
5
6
7
8    <-# end of first while
2
3
4    <-# end of second while

所以问题必须是关于全局/局部范围的事情,但我如何才能只使用我在顶部为所有函数调用定义的全局变量$PROGRESS?

管道创建一个新的上下文来执行传递给它的指令。如果将以下行添加到代码中,则会看到警告:

#beggining of your code ...
#second while loop
sudo cat /root/.virtualServices | while read -r name ipAddr (3 times)
do
<do something>
updateprogress
done
echo $PROGRESS #will display '2'

若要解决此问题,应在没有管道的情况下重构while循环,如下所示:

while read -r name ipAddr
do
#some instructions
done < "path/to/the/file"

使用流重定向不会创建新的上下文,并且会产生预期的结果

最新更新