Wie man Bash für sh in Ubuntu benutzt

13

Ich installiere ein riesiges Programm, dessen Ressourcen als rpmDatei vorliegen. Es klebte an der Linie von

#!/bin/sh
SCITEGICPERLBIN=`dirname $0`
SCITEGICPERLHOME=`dirname $SCITEGICPERLBIN`
if [ $SCITEGICPERLHOME == "." ]

Anscheinend shfunktioniert bashRed Hat Linux mit dieser Syntax, aber es gibt den Fehler unexpected operatorin Ubuntu.

Ich kann das Skript nicht in ändern, bashda das Skript aus dem rpmPaket stammt. Ich kann das rpmPaket extrahieren und neu packen , aber möglicherweise gibt es viele solcher Skripte.

Gibt es eine Möglichkeit, die Shell-Standardeinstellung so zu ändern, dass sie #!/bin/shals bashoder als alles andere behandelt wird, was mit dem [Operator umgehen kann ?

Googlebot
quelle
5
Das einzige, was falsch ist ==, ist das , was sein sollte =. Das und die Variablenerweiterungen sollten in doppelte Anführungszeichen gesetzt werden.
Kusalananda
4
[ist kein Operator, sondern ein eingebauter Befehl, der aufgerufen wird test. Der unerwartete Operator ist ==und sollte durch ersetzt werden, =da er nicht POSIX-kompatibel ist.
schily
Das zweite einzige, was falsch ist, ist, $SCITEGICPERLHOMEdass zitiert werden sollte.
l0b0
12
Sie sollten sich beim Autor des Programms beschweren. Wenn sie verwenden #!/bin/sh, sollten sie sicherstellen, dass sie nur POSIX-Shell-Funktionen verwenden, keine bashErweiterungen. Dieser Programmierer ist sehr schlampig. Er sollte entweder seinen Code reparieren oder verwenden #!/bin/bash.
Barmar
Für Leute, die sich über ähnliche Themen wundern, gibt es hier eine Liste von " Bashisms ". Siehe auch diese Frage .
Captain Man

Antworten:

21

Es gibt mehrere Programme, die die Sprache von implementieren /bin/sh. Auf Ubuntu /bin/shist dash, das so konzipiert ist, dass es schnell ist, wenig Speicher benötigt und nicht viel mehr als das Minimum unterstützt, das von erwartet wird /bin/sh. Auf RHEL /bin/shist bash langsamer und benötigt mehr Speicher, hat aber mehr Funktionen. Eine dieser Funktionen ist der ==Operator für die [bedingte Syntax. Dash unterstützt [, was eine grundlegende sh-Funktion ist, aber keinen ==Operator hat, der eine bash- (und ksh- und zsh-) Erweiterung ist.

Sie können Ihr System auf bash umstellen. Unter Ubuntu gibt /bin/shes eine symbolische Verknüpfung zu dash. Sie können bashstattdessen einen symbolischen Link zu erstellen. Aktuelle Versionen von Debian und Ubuntu (und Derivaten) machen dies zu einer Installationsoption von Dash. Führen Sie zum Ändern den Befehl aus

sudo dpkg-reconfigure dash

und antworten Sie mit "Ja", um den Gedankenstrich beizubehalten, /bin/shoder mit "Nein", um zur Bash zu wechseln.

Sie können Bash als behalten /bin/sh, aber es wird Ihr System ein bisschen langsamer machen. Es ist sogar vorstellbar, dass einige Systemskripte nicht mit bash kompatibel sind, obwohl dies unwahrscheinlich ist, da bash meistens eine Übermenge von Gedankenstrichen ist.


Für Distributionen, die keine Schnittstelle zur Auswahl zwischen Implementierungen von haben /bin/sh, lesen Sie hier, wie Sie zu bash wechseln.

sudo ln -s bash /bin/sh.bash
sudo mv /bin/sh.bash /bin/sh

Lassen Sie ein Terminal geöffnet und prüfen Sie, ob Sie danach noch einige shSkripte ausführen können . Wenn Sie diesen Befehl durcheinander bringen, wird Ihr System unbrauchbar. (Übrigens, der Grund, warum ich die oben genannten Mehrfachbefehle anstelle der unkomplizierten Befehle verwendet habe sudo ln -sf bash /bin/sh, ln -sfist nicht atomar. In dem zugegebenermaßen unwahrscheinlichen Fall, dass Ihr Computer während dieses Vorgangs abstürzt, müssen Sie von einem Notfallmedium booten, um ihn wiederherzustellen. Ist dagegen mvatomar.)

So stellen Sie den Bindestrich wieder her als /bin/sh:

sudo ln -s dash /bin/sh.dash
sudo mv /bin/sh.dash /bin/sh

Beachten Sie, dass das /bin/bashUmschalten auf dash zu einem Fehlschlagen von Skripten führen kann , wenn sh in Ihrer Distribution standardmäßig aktiviert ist, da bash viel mehr Funktionen als dash enthält. Bash-Skripte sollten mit beginnen #!/bin/bash, und Skripte, die mit beginnen, #!/bin/shsollten keine bash-spezifischen Funktionen verwenden, aber Distributionen, die mit bash ausgeliefert werden, verwenden /bin/shmöglicherweise bash-spezifische Funktionen in #!/bin/shSkripten, die für diese Distribution spezifisch sind (es ist in Ordnung, solange keine Benutzererwartungen bestehen) kann zu dash as wechseln /bin/shund es gibt keine Erwartung, dass diese Skripte auf einer anderen Distribution funktionieren).

Gilles 'SO - hör auf böse zu sein'
quelle
Meiner nicht so bescheidenen Meinung nach /bin/shist es ein Fehler im System (das Paket mit dem Skript) oder im Bash- shModus , wenn ein Skript fehlschlägt, wenn es Bash ist . Wie Stephen sagt, erlaubt das System explizit das Zurücksetzen /bin/shauf Bash über dpkg-reconfigure. Diesbezüglich wird es auch
ilkkachu
5
@ilkkachu Ja, wenn ein Skript fehlschlägt, wenn /bin/shBash ist, ist es ein Fehler. Es treten jedoch Fehler auf. Ich empfehle, die Standardeinstellung beizubehalten, wenn Sie nicht in der Lage und bereit sind, solche Fehler zu diagnostizieren, da andere Personen sie für Sie getestet haben. Ich habe dash verwendet, wie /bin/shzuvor, als es offiziell von Debian unterstützt wurde, aber dies war ein Risiko, das ich eingegangen bin, da ich wusste, dass ich in der Lage sein würde, mit dem Problem umzugehen, wenn etwas passiert.
Gilles 'SO- hör auf böse zu sein'
Beachten Sie, dass manuell überschriebene Symlinks zu jeder Konfiguration wiederhergestellt werden, die bei debconfder nächsten dashAktualisierung gespeichert wird. Zugegebenermaßen kommt dies bei Systemen, auf denen Debian stable ausgeführt wird, nicht oft (wenn überhaupt, in einer bestimmten Version) vor.
Stephen Kitt
36

Um shzu bash(anstelle dashder Standardeinstellung) zu wechseln , konfigurieren Sie dashes neu (ja, es ist etwas kontraintuitiv):

sudo dpkg-reconfigure dash

Hier werden Sie gefragt, ob Sie dashdie Standard-System-Shell sein möchten . Antworten Sie mit "Nein" ( Tabdann Enter) und bashwerden stattdessen zur Standardeinstellung ( dh /bin/sh zeigen auf /bin/bash).

Stephen Kitt
quelle
1
Ihre Lösung ist in der Tat die vernünftigste, aber ich habe eine andere Antwort akzeptiert, da die Problematik durch detaillierte Beschreibungen geklärt wurde. Entschuldigung für jegliche Unannehmlichkeiten.
Googlebot
@Googlebot Sie müssen sich nicht entschuldigen. Die Auswahl der akzeptierten Antwort ist das Privileg des Fragestellers. Und ich habe ein goldenes Abzeichen bekommen ;-).
Stephen Kitt