zsh 是否尊重 shebang bin/sh 所以可以使用 dash ?

zsh 是否尊重 shebang bin/sh 所以可以使用 dash ?

我有一个简单的脚本,涉及forbash 中的循环,我试图在 zsh 中使用它。我曾假设 shebang 将确保使用符合 POSIX 标准的 shell(在我的系统上/bin/sh -> dash*),因此不会出现任何问题。

MWE 脚本ITEMS实际上是列出软件包的命令的输出,例如ITEMS=$(pip freeze)

#!/bin/sh

# ITEMS=$(pip freeze)  # Example of useful command

ITEMS="Item1
Item2
Item3"  # Dummy variable for testing

for ITEM in $ITEMS; do
    echo $ITEM
    echo Complete
done

这是我尝试在以下位置运行脚本时的输出zsh

$ source scratch.sh
Item1
Item2
Item3
Complete  # Undesired

$ . ./scratch.sh
Item1
Item2
Item3
Complete  # Undesired

$ bash scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete  # Desired

$ sh scratch.sh
Item1
Complete
Item2
Complete
Item3
Complete  # Desired

当我在 bash 终端中运行它时,它工作正常。我想我误解了 shebang 是如何解释的zsh?有人可以向我解释一下应该如何使用它,以便当我运行时source scratch.sh或者. ./scratch.sh我有与运行时相同的输出sh scratch.sh吗?我知道我可以修改我的 for 循环脚本以使其zsh与本机兼容bash,但我想使用,/bin/sh -> dash因此我始终使用 posix 兼容的 shell,而不必担心 bashisms 或 zshisms。

抱歉,如果这是一个基本问题,我确实搜索了zsh,posix和 shebang 但没有找到类似的问题。

答案1

shebang 仅在直接执行脚本时才会产生影响没有指定如何运行它;也就是说,使用类似./scratch.sh/path/to/scratch.sh的东西将其放入您的目录中PATH并仅使用scratch.sh.

如果您使用其他命令运行它,它将控制它的执行情况(覆盖 shebang)。如果你使用bash scratch.sh,它会运行在bash;如果你使用zsh scratch.sh,它会运行在zsh;如果您使用sh,它可以在您的系统上运行shdash在您的具体情况下)。

如果您使用source scratch.shor . scratch.sh,它会运行在当前外壳,无论那是什么。这就是.和命令的全部目的source。再次强调,这里的 shebang 被忽略了。

答案2

你不能那样做。. script或者source script只是包含script,它不会分叉一个单独的标准或非标准 shell 来执行此操作。至于shebangs,因为zsh(当你来源一个脚本而不是执行它)他们只是评论。

不过,您可以指示zsh(尝试)暂时模拟标准 shell。 YMMV。

emulate sh -c '. ./scratch.sh'

emulate which_sh -c strstr使用暂时有效的指定仿真进行评估,更重要的是,将使其“坚持”评估期间定义的任何函数str,从而导致仿真模式在其执行期间自动打开。

相关内容