In den meisten Shell-Skripten, die ich gesehen habe (außer denen, die ich selbst nicht geschrieben habe), ist mir aufgefallen, dass der Shebang auf eingestellt ist #!/bin/sh
. Das überrascht mich nicht wirklich bei älteren Skripten, aber es gibt es auch bei relativ neuen Skripten.
Gibt es einen Grund für die Bevorzugung /bin/sh
über /bin/bash
, da so bash
ziemlich allgegenwärtig ist, und oft standardmäßig auf vielen Linux und BSD Maschinen gehen zurück mehr als ein Jahrzehnt?
/bin/sh
wenn Sie keine bestimmtenbash
Funktionen verwenden. Eines Tages könnte es sein, dass Sie eines Ihrer Skripte auf einem System verwenden müssen, auf dem es nicht installiert ist (Remote-Server, eingebetteter Computer ...)...the answers so far are fairly subjective...
Eine "subjektive" Aussage ist per Definition im Wesentlichen meinungsbasiert./bin/bash
sollte nur verwendet werden, wenn bash ausdrücklich benötigt wird. In über 40 Jahren als Entwickler habebash
ich es lange zuvor fast nie ausdrücklich gebraucht, außer beim Testen. (Ich bemühe mich auch, Shell-Erweiterungen zu vermeiden, aber die meisten meiner Skripte sind für die Verteilung bestimmt.) Viele Skripte im Netz sollten auch für eine breite Verwendung gedacht sein.Antworten:
/bin
.quelle
/bin/sh
ist schneller, wenn nichtbash
, gibt es noch ein paar Systeme wie OS / X oder RHEL, wo es/bin/sh
istbash
./bin/sh
ist/bin/bash
. Ubuntu, das von bash zu dash wechselte, hat sie alle kaputt gemacht.#!/bin/bash
wenn sie Bash wollten (daran ist nichts auszusetzen!). Die Änderung wurde größtenteils in Debian durchgeführt. Es verbesserte die Benutzererfahrung und hatte messbare Auswirkungen auf die Startzeit des Systems. Es wirkt sich auch positiv auf die Sicherheit aus, siehe "Shellshock".Die meisten Systemskripte in Linux (mit Debian-Bezug: Ubuntu, Mint usw.) sind so geschrieben, dass sie in dem schnelleren Strich ausgeführt werden können, der in diesen Systemen die Standardeinstellung / bin / sh ist. Der Grund ist zweifach:
Geschwindigkeit des Systems. Ein kleinerer Strichcode wird schneller geladen und auch schneller ausgeführt. Mit einigem (kleinen?) Zusätzlichen Aufwand (Kosten) für Programmierer von Shell-Skripten.
Sicherheit. Die Vielfalt der Muscheln trägt zur Widerstandsfähigkeit gegen Bugs bei. Debian-Systeme waren größtenteils nicht anfällig für Shellshock, da die Standard-Shell keine solche Anfälligkeit aufwies.
Bash ist in der Tat die Standard-Shell für Benutzer , da sie leistungsfähiger ist und viel mehr Elemente enthält, die das Codieren erleichtern. Dies ist auch die Standardeinstellung
sh
in Mac OS (diejenige, die mit / bin / sh verknüpft ist). Der Aufrufbash
mit demsh
Linknamen von startet jedoch als posix-kompatible Shell.quelle
eval
mit der damit verbundenen Sicherheitsanfälligkeit befassen. In ähnlicher Weise kann es ohne eingebaute Regex-Unterstützung erforderlich sein, externe Befehle (mit einem hohen Leistungsnachteil) für den Abgleich auch innerhalb einer einzelnen Zeile usw. zu verwenden.Andere haben darauf hingewiesen, dass die Prämissen der Frage, dass die Bourne Again-Shell standardmäßig und allgegenwärtig ist, völlig falsch sind.
Darüber hinaus gibt es in der Tat gute Gründe, etwas anderes als die Bourne Again-Shell für die Interpretation von Shell-Skripten zu verwenden. Diese Gründe Ubuntu und Debian großes Projekt, über eine Reihe von Jahren motiviert, bashisms zu entfernen und so viele der Shell - Skripte ausführen , indem der Systeminitialisierung (die eine war , um viel von Shell - Skripten mit System 5
rc
) und Paket Installation / Deinstallation verwenden die Debian Almquist-Shell anstelle der Bourne Again-Shell.Einfach ausgedrückt: Die Bourne Again-Shell ist nicht der schnellste Shell-Interpreter für ein POSIX-konformes Shell-Skript. Wenn man also seine Shellskripte POSIX-konform machen kann, indem man sie mit einem leichteren Programm wie der Debian Almquist-Shell interpretiert, wird das System eine bessere Leistung bringen. (Am Ende musste Debian geringfügige Anpassungen an der Almquist-Shell vornehmen, um einige Nicht-POSIX-Shell-Konstrukte zu unterstützen, die einfach zu tief und weit eingebettet und zu nützlich waren, um sie loszuwerden.)
Das Ergebnis war ein deutlicher Anstieg der Bootstrap-Leistung.
Es sind also zwei verschiedene Klassen von Shell zu betrachten:
Beachten Sie, dass es zu einfach ist, dies als "Bevorzugen
/bin/sh
" zu bezeichnen. Debian hatte tatsächlich mindestens zwei Ziele:Gegenüber Administratoren, die die Debian Almquist-Shell, die Z-Shell (im POSIX-Modus), die Bourne Again-Shell (im POSIX-Modus), die MirBSD Korn-Shell und andere verwenden
/bin/sh
, gab es entweder ...… Die Skripte so portabel wie möglich zu gestalten, damit das Umstellen der zugeordneten
/bin/sh
Elemente keine Probleme verursacht; oder… Dass nicht portierbare Skripte explizit auf das richtige Interpreterprogramm abzielen , anstatt nur diese
/bin/sh
Zuordnung zu erwarten .Es wurde die Debian Almquist-Shell
/bin/sh
anstelle der Bourne-Shell als Standardzuordnung festgelegt , so dass diejenigen Skripte, die POSIX-konform (oder genauer gesagt, Debian Policy Manual-konform) waren, schneller ausgeführt wurden.Und wenn man sich einmal damit befasst, kann man natürlich noch viel weiter gehen. wie die Effizienz Kompromisse wie
/bin/true
und/usr/bin/clear
als Shell-Skripte oder kompilierte Programme zu berücksichtigen . Aber das geht zum Glück über den Rahmen dieser Antwort hinaus. ☺Nichts davon ist sehr neu, und natürlich nicht einmal Unix-spezifisch. Vor der Jahrhundertwende habe ich einen Befehlszeileninterpreter geschrieben und veröffentlicht, der sowohl in "interaktiven" als auch in "nicht interaktiven" Varianten verfügbar war. Dabei wurde genau diese Unterteilung in der Dokumentation erläutert und der Unterschied zwischen den Variablen
COMSPEC
und derOS2_SHELL
Umgebungsvariablen festgestellt . Ebenso geht die Diskussion über das Entfernen von Bashismen in Debians System Vrc
und über das Installieren / Entfernen von Paketen auf die neunziger Jahre zurück.Weitere Lektüre
/bin/sh
. Ubuntu-Wiki./bin/sh
. Debian-Wiki.quelle
Schily Bourne Shell
Manpage unter schilytools.sourceforge.net/bosh.html geeignet sind, den Leuten zu ermöglichen, zu verstehen, wie man ein portables Skript schreibt (das hängt nur vonBourne Shell features
ab 1989 ab). Was ich tat, war, jede Verbesserung zu erwähnen, die nicht in alten Bourne Shells war. Übrigens: Ich bin auch daran interessiert, eine Liste von Bashismen in Strichen zu kennen.Ja. @Marcos ausgezeichnete Antwort umreißt dies gut.
Wenn Sie Ihre eigenen Skripte schreiben, sollten Sie den Shebang auf die allgemeinste Sache richten, gegen die Sie getestet haben.
Ist auf meinem System (Centos 6.6)
sh
verknüpft mitbash
:Dies bedeutet, dass ich immer
#!/bin/bash
in meinem Shebang verwende, es sei denn, ich habe überprüft, dass mein Skript keine Bashims enthält.Indem Sie den shebang auf
#!/bin/sh
Sie setzen, versprechen Sie, dass das Skript mit allen Implementierungen von funktioniertsh
.Dies ist ein viel größeres Versprechen, als zu sagen, dass das Skript mit bash funktioniert.
Hier ist ein Beispiel für ein Skript, das sich abhängig von
sh
der vom System verwendeten Implementierung falsch verhält :Bei Verwendung
bash
des Skripts wird gedruckt:Bei Verwendung
dash
des Skripts wird gedruckt:Wenn ich verwenden möchte,
#!/bin/sh
was muss ich tun?checkbashisms
- Beachten Sie, dass nicht alle Bashims gefunden werden. Ich habe den Bashismus oben in meinem Drehbuch nicht gefundensh
Implementierung. Ichdash
teste normalerweise mit , erwarte jedoch, dass einige Bashismen oder Dashims noch durchrutschen können.Die DashAsBinSh-Seite im Ubuntu-Wiki enthält viele interessante Informationen.
quelle
/bin/sh
; nur die POSIX-konformen.Der einzige verbleibende Grund, ein Shell-Skript anstelle eines Skripts in einer leistungsfähigeren und ergonomischeren Sprache zu schreiben, besteht darin, dass die Portabilität auf Legacy-Systeme mit unbekannter installierter Software wichtiger ist als jeder andere Faktor .
/bin/sh
ist der einzige Skript-Interpreter, der für alles verfügbar ist, was sich Unix nennt. Aber auf einer Menge älterer Systeme/bin/sh
und den damit verbundenen Dienstprogrammen ist die POSIX.1-1996-Spezifikation für "Shell und Dienstprogramme" nicht einmal konform, geschweige denn modernere. Standardkonforme Tools sind ein optionales Add-On, das an/usr/xpg4
einem solchen nicht offensichtlichen Ort installiert wird . 1 Das Schreiben von Skripten in die Portable-Subset-Shell-Sprache ist noch mühsamer und fehleranfälliger als das Schreiben von Skripten in die POSIX-Shell-Sprache. (Lesen Sie ein von Autoconf erstelltesconfigure
Skript einmal durch, wenn Sie mir nicht glauben. Nur das Setup sollte ausreichen, um Sie zu überzeugen.)Wenn Sie jedoch davon ausgehen können, dass ein anderer Skriptinterpreter installiert ist (z. B. Bash), können Sie davon ausgehen, dass ein Interpreter für eine bessere Skriptsprache installiert ist. Perl zum Beispiel ist mit größerer Wahrscheinlichkeit verfügbar als Bash.
Deshalb sollten Sie niemals ein
#! /bin/bash
Skript schreiben , denn wenn dies eine Option ist, ist auch eine bessere Sprache eine Option.1 Zum Beispiel haben Solaris 10 und älter die ursprüngliche Bourne-Shell als ausgeliefert
/bin/sh
. Ich wurde informiert, dass Solaris 11 es auf ksh93 aktualisiert hat.quelle
/bin/sh
handelt es sich nicht um POSIX.1-1996, sondern um eine ursprüngliche Bourne-Shell vor POSIX-Syntax. Das macht#!/bin/sh
die Ausführung von Skripten mit diesen Releases zu einem sehr schlechten Erlebnis. Portable Skripte unter Solaris werden verwendet,#!/usr/xpg4/bin/sh
die unter anderen Betriebssystemen nicht sehr portabel sind. Auf dem neuesten Solaris, Oracle Solaris 11 veröffentlicht 2011 erste,/bin/sh
ist ein modernes ,ksh93
die mit den letzten POSIX - Spezifikationen erfüllt, und viele moderne Erweiterungen hat.ash
die mit busybox geliefert werden), und ich glaube, zwol hat recht, dass Perl häufiger verfügbar ist als bash.bash
Sie in keiner Weise mit Ihrer hochmeinenden und nicht sachlichen Behauptung überein, dass "wenn verfügbar, dann ist dies eine bessere Sprache, so dass Sie niemalsbash
Code schreiben sollten ". Außerdem sollten Sie, wie @sixtyfootersdude betont, immer verwenden, es#!/bin/bash
sei denn, Sie haben getestet, dass Ihr Skript mit einer POSIX-Shell funktioniert.Sie sollten entweder tatsächlich verwenden
oder
Auf diese Weise rufen Sie eine der Shells auf, je nachdem, wie sie auf diesem System installiert sind.
Verwenden Sie zur Erhöhung der Sicherheit ( z. B. bei Neustarts durch Einzelbenutzer) eine
sh
andere Verwendungbash
.quelle
the advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.
Dies gilt wahrscheinlich auch fürsh
undbash
.#!/bin/env
in einem portablen Skript nichts verwenden. Man kann durchaus davon ausgehen, dass/bin/sh
es eine funktionsfähige, POSIX-kompatible Shell gibt. Andererseits hat keines meiner Systeme eine/bin/env
./bin/sh
. Für POSIX ist dies nicht erforderlich. Stattdessen werden andere Regeln definiert, um eine POSIX-kompatible Umgebung auf einer POSIX-zertifizierten Plattform zu erhalten./usr/bin/env
ist nicht allgemein verfügbar ...