Bash 管道中的变量不递减

Bash variable not decrementing in a pipeline

第一个例子中的变量 x 没有递减,而在第二个例子中它起作用了。为什么?

无效示例:

#!/bin/bash

x=100
f() {
  echo $((x--)) | tr 0-9 A-J
  # this also wouldn't work: tr 0-9 A-J <<< $((x--))
  f
}
f

工作示例:

#!/bin/bash

x=100
f() {
  echo $x | tr 0-9 A-J
  ((x--))
  # this also works: a=$((x--))
  f
}
f

我认为它与子外壳有关,因为我认为管道中的各个命令在子外壳中是 运行。

如果您不使用管道(并避免子 shell 分叉),它会递减:

x=10

f() {
   if ((x)); then
      echo $((x--))
      f
   fi
}

然后将其命名为:

f

它将打印:

10
9
8
7
6
5
4
3
2
1

由于递减发生在子shell内部,因此当前shell看不到x的递减值并进入无限递归。


编辑: 您可以尝试以下解决方法:

x=10

f() {
   if ((x)); then
      x=$(tr 0-9 A-J <<< $x >&2; echo $((--x)))
      f
   fi
}

f

要获得此输出:

BA
J
I
H
G
F
E
D
C
B