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 înbash5
saubash4
(acest lucru vă permite, de asemenea, să avețibash
v4 șibash
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 înbash5
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ă!)
.