Du hast es verkehrt herum. /bin/shist heutzutage fast nie mehr eine Bourne-Muschel, und es ist dann, wenn Sie ein Problem haben, wenn Sie einen She #! /bin/sh-Bang verwenden.
Die Bourne-Shell war eine Shell, die Ende der 70er Jahre geschrieben wurde und die vorherige Thompson-Shell (auch als "Shell" bezeichnet sh) ersetzte . In den frühen 80er Jahren hat David Korn einige Erweiterungen für die Bourne-Shell geschrieben, einige Fehler behoben und Ungeschicklichkeiten im Design behoben (und einige eingeführt) und sie als Korn-Shell bezeichnet.
In den frühen 90er Jahren spezifizierte POSIX die sh Sprache basierend auf einer Teilmenge der Korn-Shell, und die meisten Systeme haben ihre Sprache jetzt /bin/shentweder in die Korn-Shell oder in eine Shell geändert , die dieser Spezifikation entspricht. Bei BSDs änderten sie schrittweise /bin/shdie Almquist-Shell (nachdem sie die Bourne-Shell aus Lizenzgründen nicht mehr verwenden konnten), einen Klon der Bourne-Shell mit einigen ksh-Erweiterungen, sodass sie POSIX-kompatibel wurde.
Heutzutage haben alle POSIX-Systeme eine Shell, die POSIX-kompatibel ist sh(meistens, aber nicht unbedingt /bin, gibt POSIX nicht den Pfad der angegebenen Dienstprogramme an). Es basiert im Allgemeinen entweder auf ksh88, ksh93, pdksh, bash, ash oder zsh², jedoch nicht auf der Bourne-Shell, da die Bourne-Shell niemals POSIX-kompatibel war³. Ein paar dieser Schalen ( bash, zsh, yashund einige pdkshDerivate ermöglichen eine POSIX-kompatiblen Modus , wenn aufgerufen , wie shund sind weniger konform auf andere Weise).
bash(die GNU-Antwort auf die Korn-Shell) ist tatsächlich die einzige Open-Source-Shell (und man könnte sagen, dass sie derzeit nur gewartet wird, da die anderen in der Regel auf ksh88 basieren, das seit den 90er Jahren keine neuen Funktionen mehr hat), die als zertifiziert wurde POSIX-konform sein sh(im Rahmen der macOS-Zertifizierung).
Wenn Sie ein Skript mit einem #! /bin/sh -She-Bang schreiben , sollten Sie eine Standardsyntax verwenden sh(und auch Standardsyntax für die in diesem Skript verwendeten Dienstprogramme verwenden, wenn Sie portabel sein möchten. Es ist nicht nur die Shell, die bei der Interpretation einer Shell beteiligt ist Skript), dann spielt es keine Rolle, welche Implementierung dieses Standard- shSyntax-Interpreters verwendet wird ( ksh, bash...).
Es spielt keine Rolle, dass diese Shells Erweiterungen über dem Standard haben, solange Sie sie nicht verwenden. Es ist wie beim Schreiben von C-Code. Solange Sie Standard-C-Code schreiben und keine Erweiterungen des einen gccoder anderen Compilers verwenden , sollte der Code unabhängig von der Compilerimplementierung einwandfrei kompiliert werden, sofern der Compiler kompatibel ist.
Hier mit dem #! /bin/shsie Bang, Ihr Hauptproblem wäre die Systeme, in denen /bin/shist die Bourne - Shell , dass zum Beispiel nicht unterstützt Standard - Features wie $((1+1)), $(cmd), ${var#pattern}... , in dem Fall , dass Sie Umgehungen benötigen wie:
#! /bin/sh -
if false ^ true; then
# in the Bourne shell, ^ is an alias for |, so false ^ true returns
# true in the Bourne shell and the Bourne shell only.
# Assume the system is Solaris 10 (older versions are no longer maintained)
# You would need to adapt if you need to support some other system
# where /bin/sh is the Bourne shell.
# We also need to fix $PATH as the other utilities in /bin are
# also ancient and not POSIX compatible.
PATH=`/usr/xpg6/bin/getconf PATH`${PATH:+:}$PATH || exit
export PATH
exec /usr/xpg4/bin/sh "$0" "$@"
# that should give us an environment that is mostly compliant
# to the Single UNIX Specification version 3 (POSIX.2004), the
# latest supported by Solaris 10.
fi
# rest of the script
Übrigens ist Ubuntu /bin/shnicht bashstandardmäßig. Es ist dashheutzutage eine Shell, die auf NetBSD basiert sh, selbst auf der Almquist-Shell, die größtenteils POSIX-kompatibel ist, außer dass sie keine Multi-Byte-Zeichen unterstützt. Auf Ubuntu und andere Debian-basierten Systemen können Sie wählen zwischen bashund dashfür /bin/shmit dpkg-reconfigure dash) 4 . shMit Debian gelieferte Skripte sollten in beiden Shells genauso funktionieren, wie sie nach dem Debian-Richtlinienstandard (einer Obermenge des POSIX-Standards) geschrieben wurden. Sie werden wahrscheinlich feststellen, dass sie auch in zshder shEmulation funktionieren oder bosh(wahrscheinlich nicht ksh93oder yashnicht mit localeingebautem Code (erforderlich für die Debian-Richtlinie, aber nicht für POSIX)).
Alle Systeme im Geltungsbereich von unix.stackexchange.com haben sh irgendwo eine POSIX . Die meisten von ihnen haben eine /bin/sh(Sie finden vielleicht sehr seltene, die kein /binVerzeichnis haben, aber das interessiert Sie wahrscheinlich nicht), und das ist im Allgemeinen ein POSIX- shInterpreter (und in seltenen Fällen eine (nicht standardmäßige) Bourne-Shell) ).
Aber shist der einzige ausführbare Shell-Interpreter, den Sie auf einem System finden können? Für die anderen Shells können Sie sicher sein, dass macOS, Cygwin und die meisten GNU / Linux-Distributionen installiert sind bash. Von SYSV abgeleitete Betriebssysteme (Solaris, AIX ...) haben im Allgemeinen ksh88, möglicherweise ksh93. OpenBSD, MirOS wird ein pdksh-Derivat haben. MacOS wird haben zsh. Aber davon gibt es keine Garantie. Es kann weder garantiert werden, ob bashnoch eine dieser anderen Shells in /binoder an einem anderen Ort installiert wird (dies ist beispielsweise bei /usr/local/binBSD-Installationen normalerweise der Fall). Und natürlich keine Garantie für die Version der Shell, die installiert wird.
Beachten Sie, dass dies #! /path/to/executablekeine Konvention ist , sondern eine Funktion aller Unix-ähnlichen Kernel ( eingeführt in den frühen 80ern von Dennis Ritchie ), mit der beliebige Dateien ausgeführt werden können, indem der Pfad des Interpreters in einer ersten Zeile beginnend mit angegeben wird #!. Es kann sich um eine beliebige ausführbare Datei handeln.
Wenn Sie eine Datei mit der ersten Zeile beginnt , deren ausführen #! /some/file some-optional-arg, beendet der Kernel - Ausführung nach oben /some/filemit some-optional-arg, dem Pfad des Skripts und die ursprünglichen Argumente als Argumente. Sie können diese erste Zeile machen, um #! /bin/echo testzu sehen, was passiert:
$ ./myscript foo
test ./myscript foo
Wenn Sie /bin/sh -anstelle von verwenden /bin/echo test, wird der Kernel ausgeführt /bin/sh - ./myscript foo, shder in gespeicherte Inhaltscode interpretiert myscriptund die erste Zeile als Kommentar ignoriert (beginnt mit #).
¹ Wahrscheinlich /bin/shist Solaris 10 das einzige System, auf dem heutzutage jeder von uns auf ein System stößt, das auf der Bourne-Shell basiert. Solaris ist eines der wenigen Unices, die sich aus Gründen der Abwärtskompatibilität dafür entschieden haben, eine Bourne-Shell dort zu belassen (die POSIX- shSprache ist nicht vollständig) Abwärtskompatibel mit der Bourne-Shell) und (zumindest für Desktop- und vollständige Server-Bereitstellungen) haben POSIX an shanderer Stelle (in /usr/xpg4/bin/sh, basierend auf ksh88), aber das hat sich in Solaris 11 geändert, wo /bin/shjetzt ksh93 ist. Die anderen sind meistens verstorben.
² Das /bin/shvon MacOS / X war früher,zsh wurde aber später auf geändert bash. Es ist nicht zshdas Hauptaugenmerk, als POSIX- shImplementierung verwendet zu werden. Der shModus besteht hauptsächlich darin, sourcePOSIX- shCode in zshSkripte einbetten oder aufrufen zu können
³ Vor kurzem hat @schily die OpenSolaris-Shell (basierend auf der SVR4-Shell, basierend auf der Bourne-Shell) so erweitert, dass sie POSIX-kompatibel ist. boshMir ist jedoch noch nicht bekannt, dass sie auf einem beliebigen System verwendet wird. Zusammen ksh88damit ist es eine zweite POSIX-kompatible Shell, die auf dem Code der Bourne-Shell basiert
4 In älteren Versionen können Sie auch mkshPOSIX verwenden lksh. Das ist die MirOS-Shell (ehemals MirBSD), die auf pdksh basiert, selbst basiert auf der Forsyth-Shell (eine weitere Neuimplementierung der Bourne-Shell).