gpt4 book ai didi

linux - Bash-4 递归的奇怪结果

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:22:20 25 4
gpt4 key购买 nike

我设计了一个简单的测试来查看 Bash 如何处理递归,但我不明白结果。

测试:

  1. 在shell中分配一个全局变量X
  2. 创建一个函数f(),它分配一个同名的变量local X
  3. local X 分配全局 X 的值,即 local X=$X
  4. 将此函数递归几次,并检查在每次递归时,它是否使用函数上一轮的全局 Xlocal X

我期望以下两种结果之一:

  • 在每次递归中,来自先前 f()local X 将是新的“全局”X,即 X 在下一个作用域中,表示每次递归都会在前一个作用域下创建一个新作用域
  • 在每次递归时,先前的local X 值将被遗忘,每个新的local X=$X 将简单地重新分配全局X 的值 我最初分配。这表明 Bash 创建了相邻的作用域。

我没有得到任何这些。我得到了一些奇怪的东西。以下是来自终端的复制粘贴。

我在 shell 中分配了一个全局变量:

user@ubuntu-zesty:~$ X=1

我在创建 local X 的 shell 中创建了一个函数 f(),将全局 X 的值赋给它,输入一个 while 循环,将 1 添加到 local X(我假设它是本地的),打印新的 local X 值,并调用自身。重复 5 或 6 次。

user@ubuntu-zesty:~$ f() { local X=$X; while [ $X -lt 6 ]; do X=$(( $X + 1 )); echo $X; sleep 1; f; done; }

然后我调用了 f(),结果却让人莫名其妙。

user@ubuntu-zesty:~$ f
2
3
4
5
6
6
5
6
6
4
5
6
6
5
6
6
3
4
5
6
6
5
6
6
4
5
6
6
5
6
6

此时它自行退出。正如预期的那样,全局 X 未受影响。

user@ubuntu-zesty:~$ echo $X
1

那么这里发生了什么?是否有时使用全局 X,有时使用 local X?如果您知道这里发生的事情,请不要向我透露血淋淋的细节。

最后,只是为了好玩,一张输出图:

 1 ==
2 ===
3 ====
4 =====
5 ======
6 ======
7 =====
8 ======
9 ======
10 ====
11 =====
12 ======
13 ======
14 =====
15 ======
16 ======
17 ===
18 ====
19 =====
20 ======
21 ======
22 =====
23 ======
24 ======
25 ====
26 =====
27 ======
28 ======
29 =====
30 ======
31 ======

规范:

  • Bash-4.4.5(1)-release
  • x86_64 Ubuntu Zesty
  • Linux 内核 4.10.0-17-generic
  • VMware Workstation 12 虚拟机

最佳答案

我认为,正如@chepner 在他的回答中完美解释的那样,可视化动态作用域 的最佳方式是稍微修改您的函数:

function f() { 
local X="$X"
while [ "$X" -lt 6 ]; do
X=$((X + 1))
echo "${FUNCNAME[*]}" "$X" # This will print the call stack
sleep 1
f
done
}

并查看值如何增加:如果您遵循输出列,则可以调试每个级别发生的情况。

$ f
f f f f f 2
f f f f f f 3
f f f f f f f 4
f f f f f f f f 5
f f f f f f f f f 6
f f f f f f f f 6
f f f f f f f 5
f f f f f f f f 6
f f f f f f f 6
f f f f f f 4
f f f f f f f 5
f f f f f f f f 6
...

关于linux - Bash-4 递归的奇怪结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43239895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com