Respektiert zsh das Shebang-Bin/SH, sodass Dash verwendet werden kann?

Respektiert zsh das Shebang-Bin/SH, sodass Dash verwendet werden kann?

Ich habe ein einfaches Skript mit einer forSchleife von Bash, das ich in Zsh zum Laufen bringen möchte. Ich war davon ausgegangen, dass der Shebang sicherstellen würde, dass eine POSIX-kompatible Shell verwendet wird (auf meinem System habe ich das /bin/sh -> dash*), sodass es keine Probleme geben würde.

MWE-Skript, wobei es ITEMSsich tatsächlich um die Ausgabe eines Befehls handelt, der Pakete auflistet, z. B 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

Dies ist die Ausgabe, wenn ich versuche, das Skript in folgendem Format auszuführen 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

Wenn ich es in einem Bash-Terminal ausführe, funktioniert es einwandfrei. Ich glaube, ich habe missverstanden, wie der Shebang von interpretiert wird zsh? Kann mir bitte jemand erklären, wie es verwendet werden soll, sodass ich beim Ausführen von source scratch.shoder . ./scratch.shdieselbe Ausgabe erhalte, als hätte ich ausgeführt sh scratch.sh? Ich weiß, dass ich mein For-Loop-Skript so ändern könnte, dass es nativ mit zshund kompatibel ist bash, aber ich möchte verwenden, /bin/sh -> dashdamit ich immer eine POSIX-kompatible Shell verwende und mir keine Gedanken über Bashismen oder Zshismen machen muss.

Entschuldigen Sie, wenn dies eine einfache Frage ist. Ich habe nach und Shebang gesucht zsh, posixaber keine ähnliche Frage gefunden.

Antwort1

Der Shebang hat nur dann eine Auswirkung, wenn Sie das Skript direkt ausführenohne anzugeben, wie es ausgeführt werden soll; das heißt, mit etwas wie ./scratch.shoder /path/to/scratch.shoder indem Sie es in ein Verzeichnis in Ihrem Verzeichnis legen PATHund einfach verwenden scratch.sh.

Wenn Sie es mit einem anderen Befehl ausführen, steuert dieser, was damit geschieht (Überschreiben des Shebang). Wenn Sie verwenden bash scratch.sh, läuft es in bash; wenn Sie verwenden zsh scratch.sh, läuft es in zsh; wenn Sie verwenden sh, läuft es in dem, shwas sich auf Ihrem System befindet ( dashin Ihrem speziellen Fall).

Wenn Sie source scratch.shoder verwenden . scratch.sh, wird es in ausgeführtdie aktuelle Shell, was auch immer das ist. Das ist der ganze Zweck der .und sourceBefehle. Und auch hier wird der ganze Kram ignoriert.

Antwort2

Das geht nicht. . scriptoder source scripteinfach einschließt script, wird dafür keine separate Standard- oder Nicht-Standard-Shell erstellt. Was Shebangs betrifft, für zsh(wenn SieQuelleein Skript stattausführenes) es sind nur Kommentare.

Sie können zshjedoch anweisen, vorübergehend eine Standard-Shell zu emulieren (oder dies zu versuchen). Ihre Abweichung kann abweichen.

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

emulate which_sh -c strstrwird mit der angegebenen, vorübergehend wirksamen Emulation ausgewertet und, was noch wichtiger ist, wird dafür sorgen, dass es an allen während der Auswertung von definierten Funktionen „klebt“ str, wodurch der Emulationsmodus während ihrer Ausführung automatisch aktiviert wird.

verwandte Informationen