Il default bash su macOS è ancora bash v3:

$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.

Di recente è stata rilasciata bash v5. La discrepanza deriva dal fatto che bash ha la licenza GPL v3 dalla versione 4. Apple non include strumenti con licenza GPL v3 con macOS.

Tuttavia, nulla vi impedisce di scaricare e installare l’ultima versione di bash.

Le nuove caratteristiche includono, tra molte altre cose, array associati (cioè dizionari) e una migliore configurazione del completamento automatico.

Mentre si potrebbe pensare che questo sia un desiderio comune, la maggior parte delle pagine che ho trovato punta semplicemente a Homebrew per scaricare e installare una versione più recente di bash.

La sfida principale nell’uso di brew è che non funziona sulla scala richiesta dai MacAdmin. brew è progettato per l’installazione di un singolo utente, dove l’utente ha i privilegi di amministratore. I flussi di lavoro di brew non sono scalabili per grandi distribuzioni controllate con un sistema di gestione.

Idealmente, ci sarebbe un installatore di pacchetti per l’ultima versione di bash. Sfortunatamente, il progetto bash non ne fornisce uno.

In questo post, mostrerò come è possibile installare l’ultima versione di bash senza brewe come costruire un pacchetto di installazione per il deployment.

Installazione manuale

Questo richiede l’installazione di Xcode o degli strumenti di linea di comando per sviluppatori.

Prima di tutto, scarica il sorgente dell’ultima versione di bash da questa pagina. Al momento in cui scrivo l’ultima versione è bash-5.0 e il file che vuoi è bash-5.0.tar.gz. Una volta scaricato, puoi espandere l’archivio nel Finder facendo doppio clic.

Aggiornamento: ho un post con alcune istruzioni aggiornate per includere le patch a bash 5.0.

Apri una finestra del Terminale e cambia directory nella directory bash-5.0 appena espansa. Poi esegui lo script configure lì.

$ cd ~/Downloads/bash-5.0$ ./configure

Il processo di configurazione richiederà un po’ di tempo, ci saranno molti messaggi che mostrano il progresso.

Una volta che il processo configure è completo. Puoi costruire bash con il comando make.

$ make

Questo costruirà il binario bash e i file di supporto nella directory corrente. Non è dove lo vogliamo alla fine, ma è probabilmente una buona idea vedere se il processo di costruzione funziona. Questo richiederà (di nuovo) un po’ di tempo. Ci saranno alcuni strani avvertimenti, ma puoi ignorarli.

Quando make ha successo, puoi effettivamente installare bash v5 con

$ sudo make install

Questo costruirà e installerà il binario bash e i file di supporto in /usr/local/bin e /usr/local. sudo è necessario per modificare /usr/local.

Se stavi solo cercando un modo per installare bash v5 senza brew, hai finito!

Ci sono altre informazioni utili nel resto del post, comunque, quindi continua a leggere!

Come interagiscono la nuova e la vecchia bash

Di default, il binario di bash v5 è chiamato bash e sarà installato in /usr/local/bin. Il macOS predefinito PATH elenca /usr/local/bin prima di /bin dove si trova il binario predefinito di bash v3, anch’esso chiamato bash.

Questo significa che quando un utente digita bash in una shell, la versione in /usr/local/bin sarà preferita alla bash v3 preinstallata.

Si può provare questo comportamento in Terminale. Poiché la shell predefinita non è ancora stata cambiata da /bin/bash il Terminale si apre ancora su bash v3. Puoi testarlo mostrando la variabile d’ambiente BASH_VERSION:

$ echo $BASH_VERSION3.2.57(1)-release

Ma quando poi esegui bash invocherà /usr/local/bin/bash, quindi eseguirà la nuova bash v5. Lo mostrerà nel prompt, ma puoi anche verificare la BASH_VERSION.

$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release

Questa potrebbe essere la configurazione che vuoi, quando vuoi usare sempre bash v5. Potrebbe portare a qualche comportamento inaspettato per alcuni utenti, però.

Un’opzione per evitare questa ambiguità è rinominare il binario in /usr/local/bin in bash5. Ma poi altri strumenti come env (menzionato sotto) non troveranno più il binario.

  • Scrivere OS X: Where PATHs come from

Nota: il PATH in altri contesti probabilmente non conterrà /usr/local/bin e confonderà ulteriormente le cose.

bash v5 e Scripting

Gli script che usano bash, dovrebbero avere il percorso completo del binario nello shebang. In questo modo, l’autore dello script può controllare se uno script viene eseguito dalla bash v3 di default (/bin/bash) o dalla più recente bash v5 (/usr/local/bin/bash o /usr/local/bin/bash5).

Si raccomanda spesso di usare il comando env nello shebang:

#!/usr/bin/env bash

Il comando env determina il percorso del binario bash nell’ambiente corrente. (cioè usando l’attuale PATH) Questo è utile quando lo script deve essere eseguito in vari ambienti dove la posizione del binario di bash è sconosciuta, in altre parole su più piattaforme Unix e Unix-like. Tuttavia, questo rende imprevedibile la versione effettiva di bash che interpreterà lo script.

Per esempio, si supponga di avere bash v5 installato nella configurazione predefinita (come /usr/local/bin/bash. Uno script con lo shebang #!/usr/bin/env bash lanciato nell’ambiente utente (cioè da Terminale) userà il più recente bash, poiché /usr/local/bin viene prima di /bin nell’ordine di ricerca.

Quando si lancia lo stesso script in un contesto diverso, ad esempio come uno script di installazione, un AppleScript, o un sistema di gestione, /usr/local/bin probabilmente non sarà parte del PATH in quell’ambiente. Quindi lo shebang env sceglierà /bin/bash (v3). Lo script verrà interpretato e potrebbe comportarsi diversamente.

Gli amministratori preferiscono la certezza nei loro ambienti gestiti. Gli amministratori dovrebbero conoscere la posizione e le versioni dei binari sui loro sistemi. Per gli script di gestione, dovresti evitare env e usare il percorso completo appropriato al binario dell’interprete desiderato.

Le soluzioni per risolvere l’ambiguità sono

  • utilizzare il percorso completo al binario nello shebang
  • gestire e aggiornare la versione aggiuntiva personalizzata di bash con un sistema di gestione
  • (opzionale) rinominare il binario bash più recente in bash5 o bash4 (questo permette anche di avere bash v4 e bash v5 disponibili sullo stesso sistema)
  • scrivere OS X: Sullo Shebang
  • Scripting OS X: Impostare il PATH negli script

Modificare la Shell di default di un utente in bash v5

Anche se abbiamo installato bash v5, la shell di default di una nuova finestra del Terminale userà ancora la bash v3 integrata.

Il percorso della shell di default è memorizzato nel record utente. Puoi cambiare direttamente l’attributo UserShell con dscl, nelle ‘Opzioni avanzate’ del pannello delle preferenze ‘Utenti & Gruppi’, o in Utility Directory.

C’è anche un comando per impostare la shell predefinita:

$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell

Il comando chsh (cambia shell) controllerà le shell consentite nel file /etc/shells. Puoi facilmente aggiungere una linea con /usr/local/bin/bash a questo file, e poi chsh funzionerà bene.

$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: 

Nota: se scegli di rinominare il binario bash, devi usare il nome cambiato in /etc/shells e con chsh.

Ricorda che solo eseguendo chsh non cambierai la shell nella finestra corrente del Terminale. È meglio chiudere la vecchia finestra del Terminale e aprirne una nuova per ottenere la nuova shell.

Pacchetto di bash v5 per la distribuzione di massa

Mentre questi passi per installare e configurare bash v5 su un singolo Mac sono abbastanza semplici, non funzionerebbero bene con un sistema di gestione per centinaia o migliaia di Mac. Vogliamo avvolgere tutti i file che make install crea in un payload dell’installatore di pacchetti.

L’opzione --help dello script configure fornisce questa utile informazione:

Di default, 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`.

Quando eseguiamo lo script configure con l’opzione --prefix crea una cartella adatta come payload per un installatore di pacchetti. Possiamo quindi usare pkgbuild per costruire e creare un installatore 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

(Nota: l’argomento --prefix richiede un percorso assoluto.)

Automatizza la creazione del pacchetto

Quindi, abbiamo il nostro flusso di lavoro per costruire un pacchetto di installazione per distribuire e configurare bash v5:

  • scaricare l’archivio
  • estrarre l’archivio
  • eseguire configure con l’argomento --prefix
  • eseguire make install per creare i file in una cartella payload
  • opzionale: rinominare il binario risultante bash in bash5 per evitare conflitti
  • aggiungere uno script postinstall che aggiunge /usr/local/bin/bash a /etc/shells se non ancora presente
  • costruire l’installatore con pkgbuild

Sembra un flusso di lavoro maturo per l’automazione. Puoi ottenere lo script da questo repository.

Puoi passare un diverso (valido) numero di versione di bash come argomento allo script, per esempio 4.4.18. (Non ho testato nulla di significativamente più vecchio.) Lo script non rileva automaticamente l’ultima versione e si basa sulla versione 5.0 quando non viene dato alcun argomento. Quando verrà pubblicato un aggiornamento a bash v5, dovrai modificare la linea della versione o eseguire lo script con un argomento.

Non ho (ancora) capito come rilevare l’ultima versione dalla pagina web di download. Una ricetta autopkg dovrà aspettare per questo. (Se qualcun altro vuole occuparsene, per favore lo faccia!)

.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.