Zsh 嵌套命令参数 $SLVL 错误?

Zsh 嵌套命令参数 $SLVL 错误?

我想知道我在 Zsh 5.2 版中观察到的某些行为是否与我偶然发现并询问的另一个可能的错误有关上一个问题

下面的代码:

zsh -c "zsh -c 'zsh -c \"echo \$SHLVL\"'"

Echo 已经出局2$SHLVL。将此与以下内容进行比较:

sh -c "zsh -c 'zsh -c \"echo \$SHLVL\"'"

3哪里有回声$SHLVL

这是否是一个可能的错误,类似于我在上一个问题

答案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改变?

相关内容