【问题标题】:Global variable is reset if loop send output to pipe如果循环将输出发送到管道,则重置全局变量
【发布时间】:2013-05-31 00:24:26
【问题描述】:

根据 bash(1) 手册页,当我运行以下命令时:

set -e
x=2
echo Start $x
while [ $((x--)) -gt 0 ]; do echo Loop $x; done | cat
echo End $x

输出将是:

Start 2
Loop 1
Loop 0
End 2

循环后(作为子shell运行)变量x重置为2。但是如果我移除管道,x将被更新:

Start 2
Loop 1
Loop 0
End -1

我需要更改 x,但我也需要管道。 知道如何解决这个问题吗?

【问题讨论】:

  • | cat 在这里做什么?它做有意义的事情吗?
  • @devnull,我认为它只是为了说明:向任何东西添加管道将意味着 while 循环在子shell中运行,并且当子shell结束时,对变量 $x 的任何更改都会丢失。
  • 是的,真正的循环很长。在循环内部,我有一些行,例如: ping -c1 Machine || STOP="YES" 在循环结束时,我 grep(1) 删除了 "icmp_seq=" 的行

标签: bash variables loops subshell


【解决方案1】:

bash 总是(至少从 4.2 开始)在子 shell 中运行管道的所有非最右边部分。如果x的值需要在调用shell中改变,你必须重写你的代码以避免管道。

一个看起来很可怕的例子:

# If you commit to one bash feature, may as well commit to them all:
#   Arithmetic compound: (( x-- > 0 ))
#   Process substitution: > >( cat )
while (( x-- > 0 )); do echo Loop $x; done > >( cat )

【讨论】:

  • @udi,了解进程替换here
  • @chepner,非常感谢!我有一个小错字,现在可以了。
猜你喜欢
  • 2016-03-15
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多