Как обновить Bash на macOS?

Одна вещь, о которой не знают многие пользователи macOS, заключается в том, что они используют полностью устаревшую версию оболочки Bash. Однако настоятельно рекомендуется использовать более новую версию Bash в macOS, поскольку она позволяет использовать новые полезные функции. В этой статье объясняется, как это сделать.

Какая версия Bash по умолчанию в macOS?

Чтобы узнать, насколько устарела версия Bash, включенная в macOS, выполните выполните следующую команду:

bash --version

У меня стоит старенькая macOS Mojave, но версия GNU Bash гораздо старее — это 3.2, которая датируется 2007 годом! Прикол в том, что она включена во все версии macOS, даже в самые новые.

Причина, по которой Apple включает такую старую версию Bash в свою операционную систему, связана с лицензированием. Начиная с версии 4.0 (преемник 3.2), Bash использует лицензию GNUv3 (GPLv3), которую Apple не поддерживает (не хочет). Версия 3.2 GNU Bash — последняя версия с GPLv2, которую Apple принимает, и поэтому придерживается ее.

Это означает, что весь мир (например, Linux) продолжает использовать новые версии Bash, тогда как пользователи macOS застряли со старой версией десятилетней давности. На момент написания этой статьи самой новой версией GNU Bash была 5.0, выпущенная в январе 2019 года.

Инструкция по обновлению оболочки вашей системы по умолчанию до новейшей версии Bash

Вам нужно сделать три вещи:

  1. Собственно, установить последнюю версию Bash.
  2. Внести новую оболочку в список доверенных.
  3. Установить новый Bash в качестве оболочки по умолчанию.

Как вы уже поняли, просто обновить существующую системную оболочку не получиться (как в Linux).

Установка

Проще всего это сделать с помощью Homebrew. Сам менеджер пакетов ставиться одной командой с сайта, хотя скорее всего он у вас уже установлен.

Далее:

brew install bash

Чтобы проверить установку, вы можете убедиться, что теперь у вас есть две версии Bash в вашей системе:

which -a bash

Первая — это новая версия, а вторая — старая версия:

/usr/local/bin/bash --version
/bin/bash --version

Поскольку каталог новой версии (/usr/local/bin) по умолчанию стоит перед каталогом старой версии (/bin) в переменной PATH, версия, используемая при простом вводе Bash, является новой. Но это еще не все.

Список доверенных

В системах UNIX есть функцию безопасности, которая ограничивает оболочки, которые можно использовать после входа в систему. Эти доверенные оболочки перечислены в файле /etc/shells. Отредактируем его из под суперпользователя (вы можете использовать любой другой редактор):

sudo nano /etc/shells

И добавим к его содержимому оболочку /usr/local/bin/bash, чтобы файл выглядел примерно так:

/etc/shells

Оболочка по умолчанию

Необходимо выполнить команду:

chsh -s /usr/local/bin/bash

Вот и все! Оболочка по умолчанию для вашего текущего пользователя теперь настроена на новую версию Bash. К этой команде можно добавить sudo и сделать тоже самое для суперпользователя.

Некоторые особенности работы с Bash-скриптами

Теперь в вашей системе существуют две версии Bash, но почти все сценарии начинаются со строки #!/bin/bash. Это означает, что если вы запустите такой скрипт, он будет интерпретирован старой версией Bash.

#!/bin/bash

В большинстве случаев это не проблема. Если вы хотите, чтобы ваш скрипт явно интерпретировался новой версией Bash, вы можете изменить начальную строку на #!/usr/local/bin/bash.

Но это решение не является переносимым, оно, скорее всего, не будет работать на других системах. Это связано с тем, что другие «нормальные» системы не имеют оболочки, расположенной в /usr/local/bin/bash (тогда как /bin/bash является почти стандартом).

Поэтому для скриптов лучше всегда использовать строку #!/usr/bin/env bash. При такой записи сценарий проверяет переменную PATH и использует первый обнаруженный исполняемый файл Bash в качестве интерпретатора. Если каталог новой версии расположен перед каталогом старой версии в PATH (что по умолчанию), то будет использоваться новая версия, и вывод скрипта будет примерно таким:

#!/usr/bin/env bash

kupereal