Defectul bash pe macOS este încă bash v3:

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

Chiar recent, a fost lansat bash v5. Discrepanța provine din faptul că bash a fost licențiat ca GPL v3 încă din versiunea 4. Apple nu include instrumente licențiate GPL v3 împreună cu macOS.

Cu toate acestea, nimic nu vă împiedică să descărcați și să instalați cea mai recentă versiune bash.

Noiile caracteristici includ, printre multe alte lucruri, array-uri asociate (adică dicționare) și o mai bună configurare a autocompletării.

În timp ce ați crede că aceasta este o dorință comună, majoritatea paginilor pe care le-am găsit vor indica pur și simplu Homebrew pentru a descărca și instala o versiune bash mai nouă.

Provocarea principală a utilizării brew este că nu funcționează la scara pe care o cer MacAdmins. brew> este proiectat pentru instalarea cu un singur utilizator, în cazul în care utilizatorul are privilegii de administrator. Fluxurile de lucru ale brew nu se adaptează la implementări mari, controlate cu un sistem de management.

În mod normal, ar exista un instalator de pachete pentru cea mai recentă versiune bash. Din păcate, proiectul bash nu oferă unul.

În această postare, voi arăta cum puteți instala cea mai recentă versiune bash fără brew și cum să construiți un pachet de instalare pentru desfășurare.

Instalare manuală

Aceasta necesită instalarea Xcode sau a Instrumentelor de linie de comandă pentru dezvoltatori.

În primul rând, descărcați sursa pentru cea mai recentă versiune bash de pe această pagină. La data scrierii acestui articol, cea mai recentă versiune este bash-5.0, iar fișierul dorit este bash-5.0.tar.gz. Odată descărcată, puteți extinde arhiva în Finder prin dublu clic.

Update: Am o postare cu câteva instrucțiuni actualizate pentru a include patch-urile la bash 5.0.

Deschideți o fereastră Terminal și schimbați directorul în directorul nou extins bash-5.0. Apoi rulați scriptul configure de acolo.

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

Procesul de configurare va dura ceva timp, vor fi o mulțime de mesaje care arată progresul.

După ce procesul configure este complet. Puteți construi bash cu comanda make.

$ make

Aceasta va construi binarul bash și fișierele suport în directorul curent. Nu este acolo unde îl dorim în final, dar este probabil o idee bună să vedem dacă procesul de construire funcționează. Acest lucru va dura (din nou) un timp. Vor exista câteva avertismente cu aspect ciudat, dar le puteți ignora.

Când make reușește, puteți instala efectiv bash v5 cu

$ sudo make install

Acest lucru va construi și instala binarul bash și fișierele de suport în /usr/local/bin și /usr/local. sudo este necesar pentru a modifica /usr/local.

Dacă ați căutat doar o modalitate de a instala bash v5 fără brew, ați terminat!

Există totuși mai multe informații utile în restul postării, așa că continuați să citiți!

Cum interacționează noul și vechiul bash

În mod implicit, binarul bash v5 se numește bash și va fi instalat în /usr/local/bin. În mod implicit, macOS PATH listează /usr/local/bin înaintea lui /bin, unde se află binarul implicit bash v3, numit, de asemenea, bash.

Aceasta înseamnă că, atunci când un utilizator tastează bash într-un shell, versiunea din /usr/local/bin va fi preferată față de versiunea preinstalată bash v3.

Puteți testa acest comportament în Terminal. Deoarece shell-ul implicit nu a fost încă schimbat din /bin/bash, Terminalul se deschide în continuare la bash v3. Puteți testa acest lucru arătând variabila de mediu BASH_VERSION:

$ echo $BASH_VERSION3.2.57(1)-release

Dar atunci când executați apoi bash va invoca /usr/local/bin/bash, deci va rula noul bash v5. Va arăta acest lucru în prompt, dar puteți verifica și BASH_VERSION.

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

Aceasta ar putea fi configurația pe care o doriți, atunci când doriți să utilizați bash v5 întotdeauna. Totuși, ar putea duce la un comportament neașteptat pentru unii utilizatori.

O opțiune pentru a evita această ambiguitate este să redenumiți binarul din /usr/local/bin în bash5. Dar atunci alte instrumente, cum ar fi env (menționat mai jos) nu vor mai găsi binarul.

  • Scripting OS X: Where PATHs come from

Nota: PATH în alte contexte probabil că nu va conține /usr/local/bin și va încurca și mai mult lucrurile.

bash v5 și Scripting

Scriptele care folosesc bash, ar trebui să aibă calea completă către binar în shebang. În acest fel, autorul scriptului poate controla dacă un script este executat de bash v3 implicit (/bin/bash) sau de bash v5 mai nou (/usr/local/bin/bash sau /usr/local/bin/bash5).

Se recomandă adesea utilizarea comenzii env în shebang:

#!/usr/bin/env bash

Comanda env va determina calea către binarul bash în mediul curent. (adică folosind PATH curent) Acest lucru este util atunci când scriptul trebuie să ruleze în diverse medii în care locația binarului bash este necunoscută, cu alte cuvinte pe mai multe platforme Unix și de tip Unix. Cu toate acestea, acest lucru face ca versiunea reală a bash care va interpreta scriptul să fie imprevizibilă.

De exemplu, să presupunem că aveți bash v5 instalat în configurația implicită (ca /usr/local/bin/bash. Un script cu shebang #!/usr/bin/env bash lansat în mediul utilizatorului (adică din Terminal) va folosi cea mai nouă versiune bash, deoarece /usr/local/bin vine înaintea lui /bin în ordinea de căutare.

Când lansați același script într-un context diferit, de exemplu ca un script de instalare, un AppleScript sau un sistem de management, /usr/local/bin nu va face probabil parte din PATH în acel mediu. Atunci shebang-ul env va alege /bin/bash (v3). Scriptul va fi interpretat și s-ar putea să se comporte diferit.

Administratorii preferă certitudinea în mediile lor gestionate. Administratorii ar trebui să cunoască locația și versiunile binarelor de pe sistemele lor. Pentru scripturile de administrare, ar trebui să evitați env și să utilizați calea completă corectă către binarul de interpretare dorit.

Soluțiile pentru a rezolva ambiguitatea sunt

  • utilizați calea completă către binarul din shebang
  • management și actualizați versiunea personalizată suplimentară a bash cu un sistem de management
  • (opțional) redenumiți binarul bash mai nou în bash5 sau bash4 (acest lucru vă permite, de asemenea, să aveți bash v4 și bash v5 disponibile pe același sistem)
  • Scripting OS X: On the Shebang
  • Scripting OS X: Setarea PATH-ului în scripturi

Schimbarea shell-ului implicit al unui utilizator în bash v5

Chiar dacă am instalat bash v5, shell-ul implicit al unei noi ferestre Terminal va folosi în continuare bash v3 încorporat.

Calea către shell-ul implicit este stocată în înregistrarea utilizatorului. Puteți modifica direct atributul UserShell cu dscl, în „Advanced Options” (Opțiuni avansate) din panoul de preferințe „Users & Groups” (Utilizatori & Grupuri) sau în Directory Utility.

Există, de asemenea, o comandă pentru a seta shell-ul implicit:

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

Comanda chsh (change shell) va verifica dacă există shell-uri permise în fișierul /etc/shells. Puteți adăuga cu ușurință o linie cu /usr/local/bin/bash la acest fișier, iar apoi chsh va funcționa bine.

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

Rețineți: dacă alegeți să redenumiți binarul bash, trebuie să folosiți numele schimbat în /etc/shells și cu chsh.

Amintiți-vă că doar rularea chsh nu va schimba shell-ul din fereastra curentă a Terminalului. Cel mai bine este să închideți vechea fereastră Terminal și să deschideți una nouă pentru a obține noul shell.

Pachetarea bash v5 pentru implementarea în masă

În timp ce acești pași pentru a instala și configura bash v5 pe un singur Mac sunt destul de simpli, ei nu ar funcționa bine cu un sistem de management pentru sute sau mii de Mac-uri. Vrem să înfășurăm toate fișierele pe care make install le creează într-un pachet de instalare.

Opțiunea --help a scriptului configure ne oferă aceste informații utile:

În mod implicit, 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`.

Când rulăm scriptul de configurare cu opțiunea --prefix acesta creează un folder potrivit ca sarcină utilă pentru un instalator de pachete. Putem folosi apoi pkgbuild pentru a construi pentru a crea un instalator 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

(Notă: argumentul --prefix necesită o cale absolută.)

Automatizați crearea pachetului

Atunci, avem fluxul nostru de lucru pentru construirea unui pachet de instalare pentru a distribui și configura bash v5:

  • descarcă arhiva
  • extrage arhiva
  • execută configure cu argumentul --prefix
  • execută make install pentru a crea fișierele într-un folder payload
  • opțional: redenumiți binarul bash rezultat în bash5 pentru a evita conflictele
  • adăugați un script postinstall care adaugă /usr/local/bin/bash la /etc/shells dacă nu este încă prezent
  • construiți programul de instalare cu pkgbuild

Acesta sună ca un flux de lucru pregătit pentru automatizare. Puteți obține scriptul din acest depozit.

Puteți trece un număr de versiune bash diferit (valabil) ca argument pentru script, de exemplu 4.4.18. (Nu am testat nimic semnificativ mai vechi.) Scriptul nu detectează automat cea mai recentă versiune și folosește implicit versiunea 5.0 atunci când nu este dat niciun argument. Când va fi publicată o actualizare la bash v5, va trebui să modificați linia de versiune sau să rulați scriptul cu un argument.

Nu mi-am dat seama (încă) cum să detectez cea mai recentă versiune de pe pagina web de descărcare. O autopkg rețetă va trebui să aștepte acest lucru. (Dacă altcineva vrea să se ocupe de asta, vă rog să o facă!)

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.