答案1
让我们稍微简化一下:
$ SHLVL=1 zsh -c 'echo $SHLVL; zsh -c "echo \$SHLVL"'
2
2
$ SHLVL=1 zsh -c 'echo $SHLVL; zsh -c "echo \$SHLVL"; true'
2
3
发生的情况是,如果最后一个命令是外部命令,zsh 会在不分叉的情况下执行它——尾部调用优化。$$
除了以下之外,您还可以通过 echoing 来观察这一点SHLVL
:在第一种情况下,zsh 的嵌套调用具有相同的 PID;在第二种情况下,嵌套调用作为子进程运行,因为父进程会留在后面运行true
。
您会看到不同的行为,sh
因为它的行为不同。也许你的sh
是 bash,它不执行任何尾部调用优化。或者可能是 ksh93,它确实执行尾调用优化,但SHLVL
即使在这种情况下也会增加。
zsh 应该SHLVL
在尾调用中递增吗?对此没有官方标准,但这是有道理的,因为尾部调用应该是一种优化,除了流程安排之外,我希望行为是相同的。 ATT ksh 的行为不同这一事实表明 zsh 不应该这样做。话又说回来,
$ SHLVL=1 ksh -c 'echo $SHLVL; exec ksh -c "echo \$SHLVL"'
2
3
SHLVL
即使使用显式的ksh93 也会增加exec
,我认为这没有意义:如果外壳被替换,为什么要SHLVL
改变?