zsh は shebang bin/sh を尊重するので dash を使用できますか?

zsh は shebang bin/sh を尊重するので dash を使用できますか?

私は、bash のループを含む簡単なスクリプトをforzsh で動作させようとしています。私は、シェバンによって POSIX 準拠のシェルが使用されること (私が使用しているシステム/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 ターミナルで実行すると、正常に動作します。 によるシェバンの解釈方法を誤解していると思います。 またはを実行したときに を実行した場合と同じ出力が得られるようにするにzshは、どのように使用すればよいか説明してもらえますか。 for ループ スクリプトを変更して、 およびにネイティブに準拠させることができることはわかっていますが、 を使用したいので、常に posix 準拠のシェルを使用して、bashisms や zshisms を心配する必要がありません。source scratch.sh. ./scratch.shsh scratch.shzshbash/bin/sh -> dash

基本的な質問であれば申し訳ありませんが、 、 shebang を検索しましたzshposix、同様の質問は見つかりませんでした。

答え1

シェバンはスクリプトを直接実行した場合にのみ効果があります実行方法を指定せずにつまり、./scratch.shまたはのようなものを使用する/path/to/scratch.shか、 のディレクトリに配置して をPATH使用するだけですscratch.sh

他のコマンドを使用して実行する場合、それがそのコマンドで実行される処理を制御します (shebang をオーバーライドします)。 を使用する場合は でbash scratch.sh実行されbash、 を使用する場合は でzsh scratch.sh実行されzsh、 を使用する場合は(特定のケースにおいて)システム上にあるshで実行されます。shdash

source scratch.shまたはを使用すると. scratch.sh現在のシェル.、それが何であれ。それが コマンドとコマンドの目的そのものですsource。ここでも、シェバンは無視されます。

答え2

そんなことはできません。. scriptまたはsource script単に をインクルードするだけでscript、それを行うために別の標準または非標準のシェルをフォークすることはありません。 シェバンに関しては、zshソーススクリプトではなく実行するそれらは単なるコメントです。

ただし、一時的に標準シェルをエミュレートするように指示する (エミュレートしようとする) ことはできますzsh。結果は状況によって異なります。

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

emulate which_sh -c strは、指定されたエミュレーションを一時的に有効にして評価しstr、さらに重要なことに、 の評価中に定義された関数に「固執」しstr、実行中にエミュレーション モードが自動的にオンになります。

関連情報