Wenn sh ein Symlink zu Bash oder Dash ist, beschränkt sich Bash auf die POSIX-Konformität, sodass es zu 100% mit sh kompatibel sein sollte.

8

Vom Unterschied zwischen Bash und Sh :

AB zur Frage: Wenn Sie /bin/sheinen Link zu bash haben, verhält sich bash beim Aufruf nicht so /bin/shwie beim Aufruf als /bin/bash. Wenn es als aufgerufen shwird, beschränkt es sich hauptsächlich auf POSIX-Konformität sowie eine begrenzte Anzahl von Erweiterungen.

Bedeutet das, dass jedes Mal, wenn ich unter Linux auf ein Shell-Skript mit einem Shebang to Sh stoße: #!/bin/shAuch wenn es sich bei dieser Distribution bin/shum einen Symlink zu einer anderen Shell wie Dash oder Bash handelt, diese zu 100% mit der Bourne-Shell kompatibel sein sollte, da es beschränkt sich auf eine begrenzte Anzahl von Erweiterungen? Also könnte ich sie in FreeBSD ausführen? Gibt es eine Ausnahme? Oder sollte ich sicher sein, dass es funktionieren wird?

Wenn also in einer Distribution bin/shein Symlink zu bin/bashund ein Skript verwendet wird #!/bin/shund das Skript Bashismus enthält, wird es nicht ausgeführt, da Bash gerne im Sh-Modus ist?

user1115057
quelle

Antworten:

16

Nein, wenn /bin/shein Symlink zu Bash Bash nur in den Posix-Modus wechselt - von Man Bash :

Wenn bash als sh aufgerufen wird, wechselt es in den Posix-Modus, nachdem die Startdateien gelesen wurden.

Wenn Sie jetzt auf der Bash-Manpage nach dem Posix-Modus suchen, werden Sie feststellen, dass einige Shell-Buildins sich anders verhalten timeoder sourceanders verhalten. Das ist alles. Bashishms wie das Schreiben functionvor dem Deklarieren einer Funktion oder das Verwenden sourceanstelle von .Still funktionieren, aber die Befehle können sich anders verhalten.

Also, wenn /bin/shein Symlink zu /bin/bashallen typischen Bashishms noch funktioniert.

Eine ziemlich umfangreiche Liste der Unterschiede im Posix-Modus finden Sie im Bash-Referenzhandbuch .

Ulrich Dangel
quelle
Ich denke, das Beste ist, alle Skripte im Checkbashism-Tool zu testen. Ich habe gehört, dass einige Distributionen wie Debian und Ubuntu (für diese muss eine Bestätigung benötigt werden) ihren bin / sh-Symlink zum Dash haben. Ist Dash mit der Bourn Shell kompatibel? Wenn ja, sollten mindestens alle Debian- und Ubuntu-Shell-Skripte unter FreeBSD in Ordnung sein.
user1115057
@ user1115057 nur Shell-Skripte mit /bin/shals shebang. Ein Shell-Skript kann weiterhin explizit verwendet werden /bin/bash. Wie auch immer, die meisten Shell-Skripte werden wahrscheinlich unter / bin / sh gut laufen, aber das Problem werden die Benutzerwerkzeuge sein, z. B. erwarten die meisten Shell-Skripte GNU-Userland, was wahrscheinlich eher ein Problem als nur ein Syntaxfehler sein wird. Ich habe auch einen Link zur Bash-Referenz hinzugefügt, der das unterschiedliche Verhalten im Posix-Modus auflistet
Ulrich Dangel
Ok, nach dem, was ich gelesen habe, verwendet BSD Asche als Bin / Sh, während Debian & Ubuntu Dash verwenden. Wenn diese Shell kompatibel ist, bedeutet dies, dass ich kein Problem mehr mit shebang #! / Bin / sh habe. Aber wie Sie sagten, wird es andere
Probleme im
@ user1115057 Dash ist auch nicht perfekt, zB wiki.ubuntu.com/DashAsBinSh/#echo sowieso die meisten Shell-Skripte sind ziemlich einfach und können ganz einfach portiert werden ... viel Glück
Ulrich Dangel
Aber Armaturenbrett und Asche sind kompatibel, oder?
user1115057
8

Es scheint einige Verwirrung um die Bourne-Muschel zu geben. Die Bourne-Shell war vor Jahrzehnten, in den Tagen vor POSIX, eine Unix-Shell. Heutzutage ist "sh" eine Implementierung oder eine andere einer Shell, die die POSIX-Spezifikation implementiert, darunter bash, pdksh, AT & T ksh, neuere Almquist-Shells und deren Derivate, die POSIX-kompatibel gemacht wurden (einschließlich des "sh" einiger BSDs Andere BSDs basieren auf pdksh und Debian ash (dash). Sogar zsh hat einen Modus, in dem es meistens POSIX-konform ist.

Die Bourne-Shell ist nicht POSIX-kompatibel und kann heutzutage auf vielen Systemen nicht gefunden werden. Wo die Bourne-Shell gefunden wird oder wo nicht, gibt es immer ein "sh", das POSIX-kompatibel ist (und nicht die Bourne-Shell), im Allgemeinen, /binwährend Solaris eine bemerkenswerte (ärgerliche) Ausnahme ist.

Beachten Sie, dass vor der Bourne-Shell und vor über 30 Jahren "sh" die Thompson-Shell war. Wir schreiben keine Skripte mehr, die mit der Thompson-Shell kompatibel sind. Ebenso sollten wir aufhören, an "sh" als die Bourne-Shell zu denken.

Jetzt ist "sh" eine Spezifikation, nicht viele manchmal inkompatible Varianten einer Implementierung. Das macht es viel einfacher, tragbare Skripte zu schreiben. Folgen Sie einfach der Spezifikation .

Das gilt für "sh" und alle Standard-Dienstprogramme (sed, cut, tr ...)

Stéphane Chazelas
quelle
+1 für "nach Spezifikation schreiben". Leider reicht das für die Portabilität oft nicht aus. Was ist zum Beispiel, wenn man in sed Muster im Egrep-Stil verwenden möchte? Die Spezifikation sieht dies nicht vor. Auf Systemen mit Gnu-basierten Dienstprogrammen (oder BusyBox) verwenden Sie sed -r. Auf Systemen mit BSD-basierten Dienstprogrammen verwenden Sie sed -E. FreeBSDs sed akzeptiert beide, aber Mac OS X akzeptiert nur -E. Und so weiter und so fort.
Dubiousjim
Das ist nebensächlich. Die Spezifikation bietet es nicht, so dass Sie es nicht portabel / POSIXly verwenden können. Wenn Sie BREs verwenden, die auf allen POSIX-konformen Systemen funktionieren, ist dies eine Garantie von POSIX. Deshalb ist es nützlich. Außerhalb von POSIX gibt es, wie Sie sagen, keine Hoffnung, da seds entweder ERE nicht unterstützen oder es mit einer anderen Option oder einer anderen ERE-Syntax unterstützen. Beachten Sie, dass EREs weniger leistungsfähig sind als BREs (nur die Syntax wird in EREs erweitert, um Ihnen das Schreiben zu ersparen. EREs können in BREs übersetzt werden, das Gegenteil ist nicht der Fall (BREs \(...\)\1haben keine Übersetzung in Standard-EREs).
Stéphane Chazelas
1
Mir ist klar, dass (POSIX) EREs keine Rückreferenzen haben. Tatsächlich habe ich an der Bearbeitung dieses Teils des Standards teilgenommen. Es ist nicht richtig, dass POSIX-EREs strikt weniger leistungsfähig sind als BREs, da im aktuellen Standard kein Wechsel für BREs definiert ist. Mir ist jedoch keine Regex-Engine bekannt, die \|BREs nicht berücksichtigt . Ich bin alle dafür, so tragbar wie möglich zu schreiben. Ich habe nur die (ich dachte weithin geschätzte) Beobachtung gemacht, dass dies schmerzhaft sein kann, und manchmal ist das Schreiben an POSIX einfach nicht möglich. Irgendwo gibt es Links, die viele solcher Perversionen aufweisen. wird nach ihnen suchen.
Dubiousjim
Guter Punkt zum Wechsel, das habe ich vergessen und stehe korrigiert. Mit sed ist es jedoch unwahrscheinlich, dass es blockiert, da Sie mehrere Ausdrücke verwenden können, um die alternativen regulären Ausdrücke abzugleichen. In der Standard-Toolchest befindet sich awk, das verwendet werden kann, wenn EREs benötigt werden. Ich finde mich sehr selten in der Standard-Toolchest wieder, und wenn ich das tue, ist es im Allgemeinen so, dass eine andere Sprache wie Perl besser geeignet ist, aber ich verstehe Ihren Standpunkt (obwohl ich immer noch denke, dass es in diesem Thread nicht darum geht, tragbare Skripte zu schreiben).
Stéphane Chazelas
Ein Beispiel, an das ich spontan gedacht habe: Shebang-Zeilen (oben in jedem Shell-Skript) sind in POSIX nicht angegeben. Ich bin mir auch nicht sicher, ob ich jemals ein System verwendet habe, das 100% POSIX-kompatibel war. Zum Beispiel sagt POSIX, dass Sie Zeilenumbrüche einfügen können, ${VAR:=stuff...here}aber viele Shells lassen Sie nicht zu, Sie müssen Anführungszeichen setzen stuff...here.
Dubiousjim