我有一个简单的脚本,涉及for
bash 中的循环,我试图在 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
,它可以在您的系统上运行sh
(dash
在您的具体情况下)。
如果您使用source scratch.sh
or . scratch.sh
,它会运行在当前外壳,无论那是什么。这就是.
和命令的全部目的source
。再次强调,这里的 shebang 被忽略了。
答案2
你不能那样做。. script
或者source script
只是包含script
,它不会分叉一个单独的标准或非标准 shell 来执行此操作。至于shebangs,因为zsh
(当你来源一个脚本而不是执行它)他们只是评论。
不过,您可以指示zsh
(尝试)暂时模拟标准 shell。 YMMV。
emulate sh -c '. ./scratch.sh'
emulate which_sh -c str
将str
使用暂时有效的指定仿真进行评估,更重要的是,将使其“坚持”评估期间定义的任何函数str
,从而导致仿真模式在其执行期间自动打开。