Domyślnym bash
na macOS jest wciąż bash v3:
$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.
Niedawno wydano bash v5. Rozbieżność pochodzi z faktu, że bash
jest licencjonowany jako GPL v3 od wersji 4. Apple nie dołącza do macOS narzędzi na licencji GPL v3.
Jednakże nic nie stoi na przeszkodzie, aby pobrać i zainstalować najnowszą wersję bash
.
Nowe funkcje obejmują, między innymi, tablice stowarzyszone (tj. słowniki) i lepszą konfigurację autouzupełniania.
Chociaż można by pomyśleć, że jest to powszechne pragnienie, większość stron, które znalazłem, po prostu wskazuje na Homebrew, aby pobrać i zainstalować nowszą wersję basha.
Głównym wyzwaniem związanym z używaniem brew
jest to, że nie działa on na skalę, której wymagają MacAdmins. brew
jest przeznaczony do instalacji dla jednego użytkownika, gdzie użytkownik ma uprawnienia administratora. Przepływy pracy brew
nie skalują się do dużych wdrożeń kontrolowanych za pomocą systemu zarządzania.
Idealnie, istniałby instalator pakietów dla najnowszej wersji bash. Niestety, projekt bash nie dostarcza go.
W tym poście pokażę, jak można zainstalować najnowszą wersję bash bez brew
i jak zbudować pakiet instalacyjny do wdrożenia.
Instalacja ręczna
Wymaga to zainstalowania Xcode lub Developer Command Line Tools.
Po pierwsze, pobierz źródło najnowszej wersji bash z tej strony. Na dzień dzisiejszy najnowsza wersja to bash-5.0
, a plik, który chcesz pobrać to bash-5.0.tar.gz
. Po pobraniu, możesz rozwinąć archiwum w Finderze przez podwójne kliknięcie.
Uaktualnienie: Mam post z kilkoma zaktualizowanymi instrukcjami, aby uwzględnić poprawki do bash 5.0.
Otwórz okno Terminala i zmień katalog na nowo rozwinięty katalog bash-5.0
. Następnie uruchom tam skrypt configure
.
$ cd ~/Downloads/bash-5.0$ ./configure
Proces konfiguracji potrwa chwilę, pojawi się mnóstwo komunikatów pokazujących postęp.
Po zakończeniu procesu configure
. Możesz zbudować bash
za pomocą polecenia make
.
$ make
To zbuduje binarkę bash
i pliki pomocnicze w bieżącym katalogu. Nie jest to miejsce, w którym chcemy je mieć, ale prawdopodobnie dobrym pomysłem jest sprawdzenie, czy proces budowania działa. To (znowu) zajmie chwilę. Pojawi się kilka dziwnie wyglądających ostrzeżeń, ale możesz je zignorować.
Gdy make
się powiedzie, możesz faktycznie zainstalować bash
v5 z
$ sudo make install
To zbuduje i zainstaluje bash
binarne i wspierające pliki w /usr/local/bin
i /usr/local
. sudo
jest wymagany do modyfikacji /usr/local
.
Jeśli szukałeś tylko sposobu na zainstalowanie bash
v5 bez brew
, skończyłeś!
Jest więcej przydatnych informacji w pozostałej części tego postu, więc czytaj dalej!
Jak nowy i stary bash współdziałają
Domyślnie binaria bash v5 nazywa się bash
i zostanie zainstalowana w /usr/local/bin
. Domyślny system macOS PATH
wymienia /usr/local/bin
przed /bin
, gdzie znajduje się domyślna binarka bash v3, również nazwana bash
.
To oznacza, że gdy użytkownik wpisze bash
w powłoce, wersja w /usr/local/bin
będzie preferowana nad preinstalowaną bash v3.
Można przetestować to zachowanie w Terminalu. Ponieważ domyślna powłoka nie została jeszcze zmieniona z /bin/bash
, Terminal nadal otwiera się na bash v3. Możesz to przetestować pokazując zmienną środowiskową BASH_VERSION
:
$ echo $BASH_VERSION3.2.57(1)-release
Ale gdy następnie uruchomisz bash
, wywoła ona /usr/local/bin/bash
, więc uruchomi nowy bash v5. Pokaże to w znaku zachęty, ale możesz również sprawdzić BASH_VERSION
.
$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release
To może być konfiguracja, której chcesz, gdy chcesz zawsze używać bash v5. Może to jednak prowadzić do pewnych nieoczekiwanych zachowań dla niektórych użytkowników.
Jedną z opcji uniknięcia tej niejednoznaczności jest zmiana nazwy binarnej w /usr/local/bin
na bash5
. Ale wtedy inne narzędzia, takie jak env
(wspomniane poniżej) nie znajdą już binarki.
- Scriptuing OS X: Where PATHs come from
Uwaga: PATH
w innych kontekstach prawdopodobnie nie będzie zawierać /usr/local/bin
i jeszcze bardziej zagmatwać sprawy.
bash v5 and Scripting
Skrypty używające bash
, powinny mieć pełną ścieżkę do binarki w shebangu. W ten sposób autor skryptu może kontrolować, czy skrypt jest wykonywany przez domyślny bash v3 (/bin/bash
) czy nowszy bash v5 (/usr/local/bin/bash
lub /usr/local/bin/bash5
).
Często zaleca się użycie polecenia env
w shebangu:
#!/usr/bin/env bash
Polecenie env
określi ścieżkę do binarki bash
w bieżącym środowisku. (tj. używając bieżącego PATH
) Jest to przydatne, gdy skrypt musi działać w różnych środowiskach, w których położenie binarki basha jest nieznane, innymi słowy, na wielu platformach uniksowych i uniksopodobnych. Jednak powoduje to, że rzeczywista wersja bash
, która będzie interpretować skrypt, jest nieprzewidywalna.
Na przykład, załóżmy, że masz bash v5 zainstalowany w domyślnej konfiguracji (jako /usr/local/bin/bash
. Skrypt z shebangiem #!/usr/bin/env bash
uruchomiony w środowisku użytkownika (tj. z Terminala) użyje nowszego bash
, ponieważ /usr/local/bin
pojawia się przed /bin
w kolejności wyszukiwania.
Gdy uruchomisz ten sam skrypt w innym kontekście, np. jako skrypt instalacyjny, AppleScript lub system zarządzania, /usr/local/bin
prawdopodobnie nie będzie częścią PATH
w tym środowisku. Wtedy env
shebang wybierze /bin/bash
(v3). Skrypt będzie interpretowany i może zachowywać się inaczej.
Administratorzy wolą pewność w swoich zarządzanych środowiskach. Administratorzy powinni znać lokalizację i wersje binariów w swoich systemach. W przypadku skryptów zarządzających należy unikać env
i używać właściwej pełnej ścieżki do żądanej binarki interpretera.
Rozwiązania rozwiązujące tę dwuznaczność to
- użycie pełnej ścieżki do binarki w shebangu
- zarządzanie i aktualizacja dodatkowej niestandardowej wersji
bash
z systemem systemu zarządzania - (opcjonalnie) zmień nazwę nowszej wersji binarnej
bash
nabash5
lubbash4
(pozwala to również miećbash
v4 ibash
v5 dostępne w tym samym systemie) - Skryptowanie OS X: Na Shebangu
- Scripting OS X: Setting the PATH in Scripts
Zmiana domyślnej powłoki użytkownika na bash v5
Nawet jeśli zainstalowaliśmy bash v5, domyślna powłoka nowego okna Terminala nadal będzie używać wbudowanego bash v3.
Ścieżka do domyślnej powłoki jest przechowywana w rekordzie użytkownika. Możesz bezpośrednio zmienić atrybut UserShell
za pomocą dscl
, w 'Opcjach zaawansowanych’ panelu preferencji 'Użytkownicy & Grupy’ lub w Narzędziu katalogowym.
Jest również polecenie do ustawiania domyślnej powłoki:
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell
Polecenie chsh
(zmień powłokę) sprawdzi dozwolone powłoki w pliku /etc/shells
. Możesz łatwo dołączyć linię z /usr/local/bin/bash
do tego pliku, a wtedy chsh
będzie działać dobrze.
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin:
Uwaga: jeśli zdecydujesz się zmienić nazwę binarną bash
, musisz użyć zmienionej nazwy w /etc/shells
i z chsh
.
Pamiętaj, że samo uruchomienie chsh
nie zmieni powłoki w bieżącym oknie Terminala. Najlepiej jest zamknąć stare okno Terminala i otworzyć nowe, aby uzyskać nową powłokę.
Pakowanie bash v5 do masowego wdrożenia
Chociaż te kroki do zainstalowania i skonfigurowania bash v5 na pojedynczym Macu są wystarczająco proste, nie działałyby dobrze w systemie zarządzania setkami lub tysiącami Maców. Chcemy zawinąć wszystkie pliki, które make install
tworzy w pakiet instalacyjny.
Opcja --help
skryptu configure
daje tę użyteczną informację:
Domyślnie,
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`.
Gdy uruchamiamy skrypt configure z opcją --prefix
, tworzy on folder odpowiedni jako ładunek dla instalatora pakietów. Możemy wtedy użyć pkgbuild
do budowania, aby utworzyć 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
(Uwaga: argument --prefix
wymaga bezwzględnej ścieżki.)
Automatyzuj tworzenie pakietu
Więc, mamy nasz przepływ pracy dla budowania pakietu instalacyjnego do dystrybucji i konfiguracji bash v5:
- download the archive
- extract the archive
- run
configure
with the--prefix
argument - run
make install
to create the files in a payload folder - optional: rename the resulting
bash
binary tobash5
to avoid conflicts - add a
postinstall
script that adds/usr/local/bin/bash
to/etc/shells
if not yet present - build the installer with
pkgbuild
To brzmi jak przepływ pracy dojrzały do automatyzacji. Możesz pobrać skrypt z tego repozytorium.
Możesz przekazać inny (poprawny) numer wersji basha jako argument do skryptu, np. 4.4.18
. (Nie testowałem niczego znacznie starszego.) Skrypt nie wykrywa automatycznie najnowszej wersji i domyślnie przyjmuje wersję 5.0
, gdy nie podano żadnego argumentu. Gdy uaktualnienie do bash v5 zostanie opublikowane, będziesz musiał zmodyfikować linię wersji lub uruchomić skrypt z argumentem.
Nie rozgryzłem (jeszcze) sposobu wykrywania najnowszej wersji ze strony pobierania. Przepis autopkg
będzie musiał na to poczekać. (Jeśli ktoś inny chce się tym zająć, proszę to zrobić!)