Standardinställningen bash
på macOS är fortfarande bash v3:
$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.
För en kort tid sedan släpptes bash v5. Diskrepansen beror på att bash
har varit licensierad som GPL v3 sedan version 4. Apple inkluderar inte GPL v3-licensierade verktyg med macOS.
Det finns dock inget som hindrar dig från att ladda ner och installera den senaste bash
-versionen.
Nya funktioner inkluderar bland annat associerade matriser (dvs. ordböcker) och bättre inställningar för automatisk komplettering.
Samtidigt som man skulle kunna tro att detta är en vanlig önskan, pekar de flesta sidor som jag har hittat helt enkelt på Homebrew för att ladda ner och installera en nyare bash-version.
Den största utmaningen med att använda brew
är att det inte fungerar i den skala som MacAdmins kräver. brew
är utformad för installation av en enda användare, där användaren har administratörsrättigheter. brew
s arbetsflöden skalar inte till stora installationer som kontrolleras med ett hanteringssystem.
Det skulle egentligen finnas en paketinstallerare för den senaste bash-versionen. Tyvärr tillhandahåller inte bash-projektet något sådant.
I det här inlägget kommer jag att visa hur du kan installera den senaste bash-versionen utan brew
och hur du bygger ett installationspaket för utplacering.
Manuell installation
Detta kräver att Xcode eller Developer Command Line Tools är installerat.
Först hämtar du källkoden för den senaste bash-versionen från den här sidan. I skrivande stund är den senaste versionen bash-5.0
och filen du vill ha är bash-5.0.tar.gz
. När du har laddat ner kan du expandera arkivet i Finder genom att dubbelklicka.
Uppdatering: Jag har ett inlägg med några uppdaterade instruktioner för att inkludera patcherna till bash 5.0.
Öppna ett Terminalfönster och byt katalog till den nyligen expanderade katalogen bash-5.0
. Kör sedan skriptet configure
där.
$ cd ~/Downloads/bash-5.0$ ./configure
Konfigureringsprocessen kommer att ta ett tag, det kommer att finnas gott om meddelanden som visar framsteg.
När configure
-processen är klar. Du kan bygga bash
med kommandot make
.
$ make
Detta kommer att bygga den binära bash
och stödfilerna i den aktuella katalogen. Det är inte där vi vill ha den i slutändan, men det är förmodligen en bra idé att se om byggprocessen fungerar. Detta kommer (återigen) att ta ett tag. Det kommer att finnas några konstiga varningar, men du kan ignorera dem.
När make
lyckas kan du faktiskt installera bash
v5 med
$ sudo make install
Detta kommer att bygga och installera bash
binärfilen och stödfilerna i /usr/local/bin
och /usr/local
. sudo
krävs för att ändra /usr/local
.
Om du bara letade efter ett sätt att installera bash
v5 utan brew
är du klar!
Det finns dock mer användbar information i resten av inlägget, så fortsätt att läsa!
Hur det nya och det gamla bash interagerar
Som standard kallas binärfilen för bash v5 för bash
och installeras i /usr/local/bin
. MacOS standard PATH
listar /usr/local/bin
före /bin
där standardbinärfilen bash v3, som också kallas bash
, finns.
Detta innebär att när en användare skriver bash
i ett skal kommer versionen i /usr/local/bin
att föredras framför den förinstallerade bash v3.
Du kan testa detta beteende i Terminal. Eftersom standardskalet ännu inte har ändrats från /bin/bash
öppnas terminalen fortfarande till bash v3. Du kan testa detta genom att visa miljövariabeln BASH_VERSION
:
$ echo $BASH_VERSION3.2.57(1)-release
Men när du sedan kör bash
kommer den att åberopa /usr/local/bin/bash
, så den kommer att köra den nya bash v5. Den kommer att visa detta i prompten, men du kan också verifiera BASH_VERSION
.
$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release
Det här kan vara den inställningen du vill ha, när du vill använda bash v5 alltid. Det kan dock leda till oväntat beteende för vissa användare.
Ett alternativ för att undvika denna tvetydighet är att byta namn på binären i /usr/local/bin
till bash5
. Men då kommer andra verktyg som env
(nämns nedan) inte att hitta binären längre.
- Scripting OS X:
Notera: PATH
i andra sammanhang kommer troligen inte att innehålla /usr/local/bin
och förvirra ytterligare.
bash v5 and Scripting
Skripter som använder bash
, bör ha den fullständiga sökvägen till binärfilen i shebang. På så sätt kan skriptförfattaren styra om ett skript exekveras av standard bash v3 (/bin/bash
) eller den nyare bash v5 (/usr/local/bin/bash
eller /usr/local/bin/bash5
).
Det rekommenderas ofta att använda kommandot env
i shebang:
#!/usr/bin/env bash
Kommandot env
kommer att bestämma sökvägen till binärfilen bash
i den aktuella miljön. (dvs. genom att använda den aktuella PATH
) Detta är användbart när skriptet måste köras i olika miljöer där platsen för bash binär är okänd, med andra ord över flera Unix och Unix-liknande plattformar. Detta gör dock den faktiska versionen av bash
som kommer att tolka skriptet oförutsägbar.
Till exempel, anta att du har bash v5 installerad i standardkonfigurationen (som /usr/local/bin/bash
. Ett skript med shebang #!/usr/bin/env bash
som startas i användarmiljön (dvs. från Terminal) kommer att använda den nyare bash
, eftersom /usr/local/bin
kommer före /bin
i sökordningen.
När du startar samma skript i en annan kontext, t.ex. som ett installationsskript, ett AppleScript eller ett ledningssystem, kommer /usr/local/bin
troligen inte att vara en del av PATH
i den miljön. Då kommer env
shebang att välja /bin/bash
(v3). Skriptet kommer att tolkas och kan bete sig annorlunda.
Administratörer föredrar säkerhet i sina hanterade miljöer. Administratörer bör veta var binärfilerna finns och vilka versioner de har på sina system. För hanteringsskript bör du undvika env
och använda den korrekta fullständiga sökvägen till den önskade binära tolkarfilen.
Lösningarna för att lösa tvetydigheten är
- använd den fullständiga sökvägen till binären i shebang
- hantera och uppdatera den ytterligare anpassade versionen av
bash
med en ledningssystem - (valfritt) döpa om den nyare binären
bash
tillbash5
ellerbash4
(detta gör det också möjligt att habash
v4 ochbash
v5 tillgängliga på samma system) - Scripting OS X: På Shebang
- Scripting OS X: Om Shebang
- Scripting OS X: Ändra en användares standardskal till bash v5
Ändra en användares standardskal till bash v5
Även om vi har installerat bash v5 kommer standardskalet i ett nytt Terminalfönster fortfarande att använda det inbyggda bash v3.
Sökvägen till standardskalet sparas i användarregistret. Du kan ändra attributet
UserShell
direkt meddscl
, i ”Avancerade alternativ” i inställningsrutan ”Användare & Grupper” eller i Directory Utility.Det finns också ett kommando för att ställa in standardskalet:
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell
Kommandot
chsh
(change shell) kontrollerar om det finns tillåtna skal i filen/etc/shells
. Du kan enkelt lägga till en rad med/usr/local/bin/bash
i den här filen och då fungerarchsh
bra.$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin:
Notera: om du väljer att byta namn på binärfilen
bash
måste du använda det ändrade namnet i/etc/shells
och medchsh
.Håll dig i minnet att om du bara kör
chsh
så ändrar du inte skalet i det aktuella Terminalfönstret. Det är bäst att stänga det gamla Terminalfönstret och öppna ett nytt för att få det nya skalet.Packning av bash v5 för massdistribution
Men även om de här stegen för att installera och konfigurera bash v5 på en enskild Mac är tillräckligt enkla, skulle de inte fungera bra med ett hanteringssystem för hundratals eller tusentals Macs. Vi vill slå in alla filer som
make install
skapar i en payload för ett installationspaket.Optionen
--help
i skriptetconfigure
ger denna användbara information:Som standard är
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`.När vi kör configure-skriptet med alternativet
--prefix
skapas en mapp som lämpar sig som nyttolast för ett paketinstallationsprogram. Vi kan sedan användapkgbuild
för att bygga för att skapa ett installationsprogram pkg:$ 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
(Observera:
--prefix
-argumentet kräver en absolut sökväg.)Automate the package creation
Så har vi vårt arbetsflöde för att bygga ett installationspaket för att distribuera och konfigurera bash v5:
- hämta ner arkivet
- extrahera arkivet
- kör
configure
med--prefix
argumentet - kör
make install
för att skapa filerna i en payload-mapp - optionellt: Omdöpa den resulterande binärfilen
bash
tillbash5
för att undvika konflikter - tillsätt ett
postinstall
skript som lägger till/usr/local/bin/bash
till/etc/shells
om det ännu inte finns - bygg installationsprogrammet med
pkgbuild
Det här låter som ett arbetsflöde som är moget för automatisering. Du kan hämta skriptet från detta arkiv.
Du kan skicka ett annat (giltigt) bash-versionnummer som argument till skriptet, t.ex.
4.4.18
. (Jag har inte testat något som är betydligt äldre.) Skriptet upptäcker inte automatiskt den senaste versionen och har som standardversion5.0
när inget argument anges. När en uppdatering till bash v5 publiceras måste du ändra versionsraden eller köra skriptet med ett argument.Jag har inte (ännu) kommit på hur jag ska upptäcka den senaste versionen från webbsidan för nedladdning. Ett
autopkg
recept får vänta på det. (Om någon annan vill ta itu med det, gör det gärna!)