bash 算术在循环中工作;循环后,var没有值

bash 算术在循环中工作;循环后,var没有值

我试图使用整数来计算循环迭代次数,但循环完成后,变量为空。我用谷歌搜索过线索,但没有运气。

我有这个代码:

#!/bin/bash

declare -i count

echo entering loop

while read var
do
  (( count++ ))
  echo $count
done

echo exited loop
echo count is $count

当我以交互方式运行它时,输入“c”后按 Ctrl+D,我得到如下输出:

$ ./example
entering loop
a
1
b
2
c
3
exited loop
count is 3

但是当我将输入输入到循环中时:

#!/bin/bash

declare -i count

echo entering loop

ls -la | while read var
do
  (( count++ ))
  # do something interesting here
  echo $count
done

echo exited loop
echo count is $count

...我得到这样的输出:

$ ./example
entering loop
1
2
3
4
5
exited loop
count is
$

为什么退出循环后不显示“count is 5”?

答案1

当您将值通过管道传输到 while 循环时,管道中的命令将在子 shell 中运行,并且当 while 循环结束时,计数器变量的值将丢失。

您可以通过使用来解决此行为流程替代而不是管道:

#!/bin/bash

declare -i count
while read var
do
  ((count++))
  echo "$count"
done < <(ls -la)
echo "count is $count"

或者您可以启用该lastpipe功能以bash在当前 shell 上下文中运行管道的最后一个命令:

https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

lastpipe
如果设置,并且作业控制未激活,shell 将运行当前 shell 环境中未在后台执行的管道的最后一个命令。

#!/bin/bash

declare -i count
shopt -s lastpipe # enable lastpipe
ls -la | while read var
do
  ((count++))
  echo "$count"
done
shopt -u lastpipe # disable lastpipe
echo "count is $count"

有关的:

答案2

请参阅 BASH 手册的第 3.2.2 节:https://www.gnu.org/software/bash/manual/bash.html

由于每个管道都在单独的子 shell 中执行,因此管道命令中计数变量的更新超出了范围。

但是,您可以在shopt -s lastpipe脚本开头使用主作用域来设置最终管道的执行。这将使计数变量更新进入与脚本的主 shell 相同的范围,从而能够恢复最终计数器值。

相关内容