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. brews 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 till bash5 eller bash4 (detta gör det också möjligt att ha bash v4 och bash 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 med dscl, 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å fungerar chsh 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 med chsh.

    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 skriptet configure 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ända pkgbuild 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 till bash5 för att undvika konflikter
    • tillsätt ett postinstallskript 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 standardversion 5.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!)

Lämna ett svar

Din e-postadress kommer inte publiceras.