关于$SHLVL的Zsh奇怪现象

3
请有人解释以下行为,好吗?
$ echo $SHLVL
1
$ zsh -c 'echo $SHLVL'
2
$ zsh -c '(echo $SHLVL)'
1

我不理解上一个结果。zsh是否会为()子shell重置$SHLVL?Bash的结果是不同的:

$ echo $SHLVL
1
$ bash -c 'echo $SHLVL'
2
$ bash -c '(echo $SHLVL)'
2

至少看起来更合乎逻辑。无论如何,当我测试时,我期望最后的结果是3。为什么没有shell给出那个结果呢?我对$SHLVL有什么误解吗?

2个回答

7
在bash中,变量SHLVL不会为子shell递增,请参见abs指南。对于嵌套的子shell,请参见BASH_SUBSHELL
在zsh中,文档说明SHLVL计算shell的数量,请参见这里,而ZSH_SUBSHELL则记录嵌套子shell的数量,请参见这里
对我来说,zsh子shell中SHLVL递减的效果是一个bug;另一个可能是将SHLVLZSH_SUBSHELL相加(一个未记录的功能?)。
$ zsh -c 'print $SHLVL $ZSH_SUBSHELL ; (print $SHLVL $ZSH_SUBSHELL)'
2 0
1 1

我也认为这是一个bug。虽然添加假设很有趣,但我认为它不太可能。如果我们继续添加更多的子shell级别,那么我们将需要$SHLVL的负值... (!?) 我会尝试确认这是否是zsh项目本身的错误。感谢您详细的答复。 - elmart
1
看这个:zsh -c '( ( (print $SHLVL $ZSH_SUBSHELL) ) )' 回显 -1 3 - Edouard Thiel
哇,你的假设似乎是正确的。因此,在zsh中,一个人真正的$SHLVL将是$SHLVL + $ZSH_SUBSHELL。我必须考虑这样的事情如何有用。乍一看,它似乎很奇怪,因为它会破坏依赖于$SHLVL的标准脚本。恭喜,你似乎发现了一个未记录的功能! - elmart

1
似乎已经修复。
我正在运行 zsh 5.7.1:
print $SHLVL $ZSH_SUBSHELL
1 0
❯ (print $SHLVL $ZSH_SUBSHELL)
1 1
❯ zsh -c 'print $SHLVL $ZSH_SUBSHELL '        
2 0
❯ zsh -c '(print $SHLVL $ZSH_SUBSHELL)'
2 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接