O padrão bash
em macOS ainda é bash v3:
$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.
Apenas recentemente, o bash v5 foi lançado. A discrepância vem do facto de bash
ter sido licenciado como GPL v3 desde a versão 4. A Apple não inclui ferramentas GPL v3 licenciadas com macOS.
No entanto, nada o impede de baixar e instalar a última bash
versão.
Novos recursos incluem, entre muitas outras coisas, arrays associados (ou seja, dicionários) e melhor configuração de auto-completamento.
Embora você pense que este é um desejo comum, a maioria das páginas que encontrei simplesmente apontará para Homebrew para baixar e instalar uma versão mais nova de bash.
O principal desafio com o uso de brew
é que ele não funciona na escala que o MacAdmins requer. brew
é projetado para instalação de um único usuário, onde o usuário tem privilégios de administrador. brew
os fluxos de trabalho de brew
não funcionam em escala para grandes implementações controladas com um sistema de gerenciamento.
De fato, haveria um instalador de pacotes para a última versão bash. Infelizmente, o projeto bash não fornece um.
Neste post, mostrarei como você pode instalar a última versão bash sem brew
e como construir um pacote instalador para deployment.
Instalação manual
Requere-se instalar o Xcode ou as Ferramentas de Linha de Comando do Desenvolvedor.
Primeiro, baixe o fonte para a última versão bash a partir desta página. A partir desta escrita, a última versão é bash-5.0
e o arquivo que você quer é bash-5.0.tar.gz
. Uma vez baixado, você pode expandir o arquivo no Finder clicando duas vezes em.
Update: Eu tenho um post com algumas instruções atualizadas para incluir os patches para bash 5.0.
Abrir uma janela do Terminal e mudar o diretório para o diretório recém expandido bash-5.0
. Então execute o script configure
lá.
$ cd ~/Downloads/bash-5.0$ ./configure
O processo de configuração levará algum tempo, haverá muitas mensagens mostrando progresso.
Após o processo configure
estar completo. Você pode compilar bash
com o comando make
.
$ make
Esta irá compilar o binário bash
e os arquivos de suporte no diretório atual. Isso não é onde nós queremos no final, mas provavelmente é uma boa idéia ver se o processo de compilação funciona. Isto vai (novamente) demorar um pouco. Haverá alguns avisos com aspecto estranho, mas pode ignorar estes.
Quando make
for bem sucedido, pode realmente instalar bash
v5 com
$ sudo make install
Isto irá construir e instalar os ficheiros bash
binários e de suporte em /usr/local/bin
e /usr/local
. sudo
é necessário modificar /usr/local
.
Se você estava apenas procurando uma maneira de instalar bash
v5 sem brew
, você está pronto!
Há mais informações úteis no resto do post, no entanto, continue lendo!
Como o novo e o antigo bash interagem
Por padrão, o binário bash v5 é chamado bash
e será instalado em /usr/local/bin
. O macOS padrão PATH
lista /usr/local/bin
antes de /bin
onde o binário bash v3 padrão, também chamado bash
, está localizado.
Isso significa que, quando um usuário digita bash
em uma shell, a versão em /usr/local/bin
será preferida em vez da bash v3.
Você pode testar esse comportamento no Terminal. Como a shell padrão ainda não foi alterada de /bin/bash
, o Terminal ainda abre para bash v3. Você pode testar isto mostrando a variável de ambiente BASH_VERSION
:
$ echo $BASH_VERSION3.2.57(1)-release
Mas quando você executar bash
ele irá invocar /usr/local/bin/bash
, então ele irá executar a nova bash v5. Ele irá mostrar isto no prompt, mas você também pode verificar a variável BASH_VERSION
.
$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release
Esta pode ser a configuração que você quer, quando você quer usar a bash v5 sempre. Pode levar a algum comportamento inesperado para alguns utilizadores, embora.
Uma opção para evitar esta ambiguidade é renomear o binário em /usr/local/bin
para bash5
. Mas então outras ferramentas como env
(mencionado abaixo) não encontrarão mais o binário.
- Scripting OS X: De onde vêm os PATHs
Note: o PATH
em outros contextos provavelmente não conterá /usr/local/bin
e ainda confundirá as coisas.
bash v5 e Scripting
Scripts usando bash
, devem ter o caminho completo para o binário no shebang. Desta forma, o autor do script pode controlar se um script é executado pelo padrão bash v3 (/bin/bash
) ou pelo mais novo bash v5 (/usr/local/bin/bash
ou /usr/local/bin/bash5
).
É frequentemente recomendado usar o comando env
no shebang:
#!/usr/bin/env bash
O comando env
determinará o caminho para o binário bash
no ambiente atual. (isto é, usando o atual PATH
) Isto é útil quando o script tem que rodar em vários ambientes onde a localização do binário bash é desconhecida, em outras palavras, através de múltiplas plataformas tipo Unix e Unix. Entretanto, isto torna a versão atual de bash
que interpretará o script imprevisível.
Por exemplo, suponha que você tenha o bash v5 instalado na configuração padrão (como /usr/local/bin/bash
. Um script com o shebang #!/usr/bin/env bash
lançado no ambiente do usuário (ou seja, do Terminal) irá usar o mais novo bash
, pois /usr/local/bin
vem antes de /bin
na ordem de busca.
Quando você lança o mesmo script em um contexto diferente, por exemplo, como um script de instalação, um AppleScript, ou um sistema de gerenciamento, /usr/local/bin
provavelmente não fará parte do PATH
naquele ambiente. Então o env
shebang irá escolher /bin/bash
(v3). O script será interpretado e poderá comportar-se de forma diferente.
Administradores preferem certeza em seus ambientes gerenciados. Os administradores devem saber a localização e as versões dos binários em seus sistemas. Para scripts de gerenciamento, você deve evitar env
e usar o caminho completo adequado para o binário do intérprete desejado.
As soluções para resolver a ambiguidade são
- usar o caminho completo para o binário no shebang
- gerir e actualizar a versão personalizada adicional de
bash
com um sistema de gestão - (opcional) renomear o mais recente
bash
binário parabash5
oubash4
(isto também permite que você tenhabash
v4 ebash
v5 disponíveis no mesmo sistema) - Scripting OS X: No Shebang
- Scripting OS X: Configurando o PATH em Scripts
Mudando o Shell padrão do usuário para bash v5
Even embora tenhamos instalado o bash v5, o shell padrão de uma nova janela de Terminal ainda usará o bash v3.
O caminho para o shell padrão é armazenado no registro do usuário. Você pode alterar directamente o atributo UserShell
com dscl
, no painel de preferências ‘Users & Groups’, ou no Directory Utility.
Tambem existe um comando para definir a shell padrão:
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell
O comando chsh
(change shell) irá verificar por shells permitidas no ficheiro /etc/shells
. Pode facilmente anexar uma linha com /usr/local/bin/bash
a este ficheiro, e então chsh
funcionará bem.
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin:
Note: se escolher renomear o binário bash
, terá de usar o nome alterado em /etc/shells
e com chsh
.
Lembrar que apenas rodar chsh
não irá alterar a shell na janela de terminal actual. É melhor fechar a janela de Terminal antiga e abrir uma nova para obter o novo shell.
Packaging bash v5 for mass deployment
Embora estes passos para instalar e configurar o bash v5 em um único Mac sejam simples o suficiente, eles não funcionariam bem com um sistema de gerenciamento para centenas ou milhares de Macs. Nós queremos envolver todos os arquivos que make install
cria em um payload do instalador de pacotes.
A opção --help
do script configure
produz esta informação útil:
Por padrão,
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`.
Quando executamos o script de configuração com a opção --prefix
, ele cria uma pasta adequada como payload para um instalador de pacotes. Podemos então usar pkgbuild
para construir para criar um instalador 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
(Nota: o argumento --prefix
requer um caminho absoluto.)
Automate the package creation
Então, temos o nosso workflow para construir um pacote instalador para distribuir e configurar o bash v5:
>
- >
- download the archive
- extract the archive
- run
configure
com o argumento--prefix
- run
make install
para criar os arquivos em uma pasta de payload - opcional: renomeie o resultado
bash
binário parabash5
para evitar conflitos - add a
postinstall
script que adiciona/usr/local/bin/bash
a/etc/shells
se ainda não estiver presente - build the installer with
pkgbuild
>
>
>
Soa como um fluxo de trabalho maduro para automação. Você pode obter o script deste repositório.
Você pode passar um número de versão bash diferente (válido) como um argumento para o script, por exemplo 4.4.18
. (Eu não testei nada significativamente mais antigo.) O script não detecta automaticamente a versão mais recente e por padrão a versão 5.0
quando nenhum argumento é dado. Quando uma atualização para bash v5 é publicada, você terá que modificar a linha da versão ou executar o script com um argumento.
Não descobri (ainda) como detectar a última versão da página de download. Uma receita autopkg
terá de esperar por isso. (Se outra pessoa quiser resolver isso, por favor faça!)