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

你不能那樣做。. scriptsource script只是包含script,它不會分叉一個單獨的標準或非標準 shell 來執行此操作。至於shebangs,因為zsh(當你來源一個腳本而不是執行它)他們只是評論。

不過,您可以指示zsh(嘗試)暫時模擬標準 shell。 YMMV。

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

emulate which_sh -c strstr使用暫時有效的指定模擬進行評估,更重要的是,將使其「堅持」評估期間定義的任何函數str,從而導致仿真模式在執行期間自動開啟。

相關內容