
我有一個簡單的腳本,涉及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
,從而導致仿真模式在執行期間自動開啟。