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 bashz systemem systemu zarządzania
  • (opcjonalnie) zmień nazwę nowszej wersji binarnej bash na bash5 lub bash4 (pozwala to również mieć bash v4 i bash 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 to bash5 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ć!)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.