Der Standard bash
auf macOS ist immer noch bash v3:
$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.
Kürzlich wurde bash v5 veröffentlicht. Die Diskrepanz ergibt sich aus der Tatsache, dass bash
seit Version 4 unter der GPL v3 lizenziert ist. Apple liefert keine GPL v3 lizenzierten Tools mit macOS aus.
Es hindert Sie jedoch nichts daran, die neueste bash
Version herunterzuladen und zu installieren.
Neue Funktionen sind unter anderem assoziierte Arrays (d.h. Wörterbücher) und eine bessere Einrichtung der Autovervollständigung.
Obwohl man meinen könnte, dass dies ein allgemeiner Wunsch ist, verweisen die meisten Seiten, die ich gefunden habe, einfach auf Homebrew, um eine neuere Bash-Version herunterzuladen und zu installieren.
Das größte Problem bei der Verwendung von brew
ist, dass es nicht in dem Umfang funktioniert, den MacAdmins benötigen. brew
ist für eine Einzelplatzinstallation konzipiert, bei der der Benutzer über Administratorrechte verfügt. Die Arbeitsabläufe von brew
skalieren nicht für große Installationen, die mit einem Managementsystem kontrolliert werden.
Genau genommen gäbe es einen Paketinstaller für die neueste Bash-Version. Leider stellt das Bash-Projekt keinen zur Verfügung.
In diesem Beitrag zeige ich, wie man die neueste Bash-Version ohne brew
installieren kann und wie man ein Installationspaket für die Bereitstellung erstellt.
Manuelle Installation
Dafür muss Xcode oder die Developer Command Line Tools installiert sein.
Zunächst laden Sie den Quellcode für die neueste Bash-Version von dieser Seite herunter. Zum jetzigen Zeitpunkt ist die neueste Version bash-5.0
und die gewünschte Datei ist bash-5.0.tar.gz
. Nach dem Herunterladen können Sie das Archiv im Finder durch Doppelklick erweitern.
Aktualisierung: Ich habe einen Beitrag mit einigen aktualisierten Anweisungen, um die Patches für bash 5.0 einzubeziehen.
Öffnen Sie ein Terminal-Fenster und wechseln Sie in das neu erweiterte bash-5.0
-Verzeichnis. Führen Sie dann das configure
-Skript dort aus.
$ cd ~/Downloads/bash-5.0$ ./configure
Der Konfigurationsprozess wird eine Weile dauern, es werden viele Meldungen erscheinen, die den Fortschritt anzeigen.
Wenn der configure
-Prozess abgeschlossen ist. Du kannst bash
mit dem make
Befehl bauen.
$ make
Dies wird das bash
Binary und die unterstützenden Dateien im aktuellen Verzeichnis bauen. Das ist nicht der Ort, an dem wir es letztendlich haben wollen, aber es ist wahrscheinlich eine gute Idee zu sehen, ob der Erstellungsprozess funktioniert. Dies wird (wieder) eine Weile dauern. Es wird ein paar seltsam aussehende Warnungen geben, aber die kann man ignorieren.
Wenn make
erfolgreich ist, kann man bash
v5 mit
$ sudo make install
installieren, was das bash
Binary und die unterstützenden Dateien in /usr/local/bin
und /usr/local
baut und installiert. sudo
wird benötigt, um /usr/local
zu modifizieren.
Wenn du nur nach einem Weg gesucht hast, bash
v5 ohne brew
zu installieren, bist du fertig!
Es gibt aber noch mehr nützliche Informationen im Rest des Beitrags, also lies weiter!
Wie die neue und die alte bash interagieren
Standardmäßig heißt die bash v5 Binary bash
und wird in /usr/local/bin
installiert. Der macOS-Standard PATH
listet /usr/local/bin
vor /bin
auf, wo sich die standardmäßige bash v3-Binärdatei, ebenfalls bash
, befindet.
Das bedeutet, dass, wenn ein Benutzer bash
in eine Shell eintippt, die Version in /usr/local/bin
gegenüber der vorinstallierten bash v3 bevorzugt wird.
Sie können dieses Verhalten in Terminal testen. Da die Standardshell noch nicht von /bin/bash
geändert wurde, öffnet sich das Terminal immer noch mit bash v3. Sie können dies testen, indem Sie die Umgebungsvariable BASH_VERSION
anzeigen:
$ echo $BASH_VERSION3.2.57(1)-release
Aber wenn Sie dann bash
ausführen, wird /usr/local/bin/bash
aufgerufen, d.h. es wird die neue bash v5 ausgeführt. Dies wird in der Eingabeaufforderung angezeigt, aber Sie können auch die BASH_VERSION
überprüfen.
$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release
Dies könnte die Einstellung sein, die Sie wollen, wenn Sie immer bash v5 verwenden wollen. Es könnte jedoch zu einem unerwarteten Verhalten für einige Benutzer führen.
Eine Möglichkeit, diese Mehrdeutigkeit zu vermeiden, ist die Umbenennung der Binärdatei in /usr/local/bin
in bash5
. Aber dann finden andere Tools wie env
(siehe unten) das Binary nicht mehr.
- Scripting OS X: Woher PATHs kommen
Anmerkung: das PATH
in anderen Zusammenhängen wird wahrscheinlich nicht /usr/local/bin
enthalten und die Dinge weiter verwirren.
bash v5 und Scripting
Skripte, die bash
verwenden, sollten den vollen Pfad zum Binary im Shebang haben. Auf diese Weise kann der Skriptautor steuern, ob ein Skript von der Standard-Bash v3 (/bin/bash
) oder der neueren Bash v5 (/usr/local/bin/bash
oder /usr/local/bin/bash5
) ausgeführt wird.
Es wird oft empfohlen, den env
-Befehl im Shebang zu verwenden:
#!/usr/bin/env bash
Der env
-Befehl ermittelt den Pfad zum bash
-Binary in der aktuellen Umgebung. (d.h. unter Verwendung des aktuellen PATH
) Dies ist nützlich, wenn das Skript in verschiedenen Umgebungen ausgeführt werden muss, in denen der Ort der Bash-Binärdatei unbekannt ist, mit anderen Worten über mehrere Unix- und Unix-ähnliche Plattformen hinweg. Allerdings wird dadurch die tatsächliche Version von bash
, die das Skript interpretiert, unvorhersehbar.
Angenommen, Sie haben die Bash v5 in der Standardkonfiguration (als /usr/local/bin/bash
) installiert. Ein Skript mit dem Shebang #!/usr/bin/env bash
, das in der Benutzerumgebung (d.h. vom Terminal aus) gestartet wird, wird das neuere bash
verwenden, da /usr/local/bin
in der Suchreihenfolge vor /bin
steht.
Wenn Sie dasselbe Skript in einem anderen Kontext starten, z.B. als Installationsskript, als AppleScript oder als Verwaltungssystem, wird /usr/local/bin
wahrscheinlich nicht Teil des PATH
in dieser Umgebung sein. Dann wird das env
shebang /bin/bash
(v3) wählen. Das Skript wird interpretiert und könnte sich anders verhalten.
Administratoren bevorzugen Gewissheit in ihren verwalteten Umgebungen. Administratoren sollten den Speicherort und die Versionen der Binärdateien auf ihren Systemen kennen. Für Verwaltungsskripte sollten Sie env
vermeiden und den korrekten vollständigen Pfad zur gewünschten Interpreter-Binärdatei verwenden.
Die Lösungen zur Behebung der Mehrdeutigkeit sind
- Verwenden Sie den vollständigen Pfad zum Binary im Shebang
- Manage und aktualisieren Sie die zusätzliche benutzerdefinierte Version von
bash
mit einem Managementsystem - (optional) die neuere
bash
-Binärdatei inbash5
oderbash4
umbenennen (dies erlaubt es auch,bash
v4 undbash
v5 auf demselben System verfügbar zu haben) - Skripting OS X: Auf dem Shebang
- Scripting OS X: Einstellen des PATH in Skripten
Die Standard-Shell eines Benutzers auf bash v5 ändern
Auch wenn wir bash v5 installiert haben, wird die Standard-Shell eines neuen Terminal-Fensters immer noch die eingebaute bash v3 verwenden.
Der Pfad zur Standard-Shell ist im Benutzereintrag gespeichert. Sie können das UserShell
-Attribut direkt mit dscl
, in den ‚Erweiterten Optionen‘ des Einstellungsbereichs ‚Benutzer & Gruppen‘ oder im Verzeichnisdienstprogramm ändern.
Es gibt auch einen Befehl, um die Standard-Shell festzulegen:
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell
Der Befehl chsh
(Shell ändern) prüft die erlaubten Shells in der Datei /etc/shells
. Sie können einfach eine Zeile mit /usr/local/bin/bash
an diese Datei anhängen, und dann funktioniert chsh
einwandfrei.
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin:
Hinweis: Wenn Sie die bash
-Binärdatei umbenennen möchten, müssen Sie den geänderten Namen in /etc/shells
und mit chsh
verwenden.
Erinnern Sie sich daran, dass die Ausführung von chsh
die Shell im aktuellen Terminalfenster nicht ändert. Es ist am besten, das alte Terminal-Fenster zu schließen und ein neues zu öffnen, um die neue Shell zu erhalten.
Paketierung der bash v5 für den Masseneinsatz
Während diese Schritte zur Installation und Konfiguration der bash v5 auf einem einzelnen Mac einfach genug sind, würden sie bei einem Verwaltungssystem für hunderte oder tausende von Macs nicht gut funktionieren. Wir wollen alle Dateien, die make install
erstellt, in eine Paket-Installations-Nutzlast verpacken.
Die --help
-Option des configure
-Skripts liefert diese nützliche Information:
Standardmäßig ist
make install' will install all the files in
/usr/local/bin,
/usr/local/libetc. You can specify an installation prefix other than
/usr/localusing
-prefix, for instance
-prefix=$HOME`.
Wenn wir das configure-Skript mit der Option --prefix
ausführen, erstellt es einen Ordner, der sich als Nutzlast für ein Paket-Installationsprogramm eignet. Wir können dann pkgbuild
verwenden, um ein Installationspaket zu erstellen:
$ cd ~/Downloads/bash-5.0$ mkdir payload$ ./configure --prefix=/Users/armin/Downloads/bash-5.0/payload$ make install$ pkgbuild --root payload --install-location /usr/local --identifier org.gnu.bash --version 5.0 bash-5.0.pkgpkgbuild: Inferring bundle components from contents of payloadpkgbuild: Wrote package to bash-5.0.pkg
(Hinweis: Das Argument --prefix
erfordert einen absoluten Pfad.)
Automatisieren Sie die Paketerstellung
So, wir haben unseren Arbeitsablauf für die Erstellung eines Installationspakets zur Verteilung und Konfiguration der bash v5:
- Herunterladen des Archivs
- Entpacken des Archivs
- Ausführen von
configure
mit dem Argument--prefix
- Ausführen von
make install
, um die Dateien in einem Nutzdatenordner zu erstellen - optional: Benennen Sie die resultierende
bash
-Binärdatei inbash5
um, um Konflikte zu vermeiden - Fügen Sie ein
postinstall
-Skript hinzu, das/usr/local/bin/bash
zu/etc/shells
hinzufügt, falls es noch nicht vorhanden ist - Erstellen Sie den Installer mit
pkgbuild
Dies klingt nach einem Arbeitsablauf, der sich für die Automatisierung eignet. Sie können das Skript aus diesem Repository beziehen.
Sie können eine andere (gültige) Bash-Versionsnummer als Argument an das Skript übergeben, z.B. 4.4.18
. (Ich habe keine wesentlich ältere Version getestet.) Das Skript erkennt die neueste Version nicht automatisch und verwendet standardmäßig die Version 5.0
, wenn kein Argument angegeben wird. Wenn ein Update auf bash v5 veröffentlicht wird, müssen Sie die Versionszeile ändern oder das Skript mit einem Argument ausführen.
Ich habe (noch) nicht herausgefunden, wie man die neueste Version auf der Download-Webseite erkennt. Ein autopkg
Rezept wird darauf warten müssen. (Wenn sich jemand anderes darum kümmern möchte, dann bitte!)