La versión por defecto de bash
en macOS sigue siendo bash v3:
$ bash --versionGNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)Copyright (C) 2007 Free Software Foundation, Inc.
Recientemente, bash v5 fue lanzado. La discrepancia viene del hecho de que bash
tiene licencia GPL v3 desde la versión 4. Apple no incluye herramientas con licencia GPL v3 con macOS.
Sin embargo, nada te impide descargar e instalar la última versión de bash
.
Las nuevas características incluyen, entre otras muchas cosas, arrays asociados (es decir, diccionarios) y una mejor configuración del autocompletado.
Aunque se podría pensar que esto es un deseo común, la mayoría de las páginas que he encontrado simplemente apuntan a Homebrew para descargar e instalar una versión más nueva de bash.
El principal desafío con el uso de brew
es que no funciona en la escala que los MacAdmins requieren. brew
está diseñado para la instalación de un solo usuario, donde el usuario tiene privilegios de administrador. Los flujos de trabajo de brew
no escalan a grandes despliegues controlados con un sistema de gestión.
En realidad, habría un instalador de paquetes para la última versión de bash. Desafortunadamente, el proyecto bash no proporciona uno.
En este post, voy a mostrar cómo se puede instalar la última versión de bash sin brew
y cómo construir un paquete instalador para el despliegue.
Instalación manual
Esto requiere Xcode o las herramientas de línea de comandos para desarrolladores para ser instalado.
Primero, descargue la fuente para la última versión de bash desde esta página. En el momento de escribir esto, la última versión es bash-5.0
y el archivo que quieres es bash-5.0.tar.gz
. Una vez descargado, puedes expandir el archivo en Finder haciendo doble clic.
Actualización: tengo un post con algunas instrucciones actualizadas para incluir los parches a bash 5.0.
Abre una ventana de Terminal y cambia de directorio al directorio bash-5.0
recién expandido. A continuación, ejecute la secuencia de comandos configure
allí.
$ cd ~/Downloads/bash-5.0$ ./configure
El proceso de configuración tomará un tiempo, habrá un montón de mensajes que muestran el progreso.
Una vez que el proceso configure
se completa. Usted puede construir bash
con el comando make
.
$ make
Esto construirá el binario bash
y los archivos de apoyo en el directorio actual. Eso no es donde lo queremos al final, pero es probablemente una buena idea ver si el proceso de construcción funciona. Esto (de nuevo) tomará un tiempo. Habrá algunas advertencias de aspecto extraño, pero puedes ignorarlas.
Cuando make
tiene éxito, puedes instalar bash
v5 con
$ sudo make install
Esto construirá e instalará el binario bash
y los archivos de apoyo en /usr/local/bin
y /usr/local
. sudo
se requiere para modificar /usr/local
.
Si sólo estaba buscando una manera de instalar bash
v5 sin brew
, ya está hecho!
Hay más información útil en el resto del post, sin embargo, así que sigue leyendo!
Cómo el nuevo y el viejo bash interactúan
Por defecto, el binario de bash v5 se llama bash
y se instalará en /usr/local/bin
. El macOS por defecto PATH
lista /usr/local/bin
antes de /bin
donde se encuentra el binario de bash v3 por defecto, también llamado bash
.
Esto significa, que cuando un usuario escribe bash
en un shell, la versión en /usr/local/bin
será preferida sobre el bash v3 preinstalado.
Puede probar este comportamiento en Terminal. Dado que el shell por defecto aún no se ha cambiado de /bin/bash
el Terminal todavía se abre a bash v3. Puede probar esto mostrando la variable de entorno BASH_VERSION
:
$ echo $BASH_VERSION3.2.57(1)-release
Pero cuando luego ejecute bash
invocará /usr/local/bin/bash
, por lo que ejecutará el nuevo bash v5. Mostrará esto en el prompt, pero también puede verificar el BASH_VERSION
.
$ bashbash-5.0$ echo $BASH_VERSION5.0.0(2)-release
Esta podría ser la configuración que desea, cuando quiere usar bash v5 siempre. Sin embargo, podría conducir a un comportamiento inesperado para algunos usuarios.
Una opción para evitar esta ambigüedad es cambiar el nombre del binario en /usr/local/bin
a bash5
. Pero entonces otras herramientas como env
(mencionadas más abajo) ya no encontrarán el binario.
- Scripting OS X: De dónde vienen los PATHs
Nota: el PATH
en otros contextos probablemente no contendrá /usr/local/bin
y confundirá aún más las cosas.
bash v5 y Scripting
Los scripts que usen bash
, deben tener la ruta completa al binario en el shebang. De esta manera, el autor del script puede controlar si un script es ejecutado por el bash v3 por defecto (/bin/bash
) o el más nuevo bash v5 (/usr/local/bin/bash
o /usr/local/bin/bash5
).
A menudo se recomienda utilizar el comando env
en el shebang:
#!/usr/bin/env bash
El comando env
determinará la ruta al binario bash
en el entorno actual. (es decir, utilizando el PATH
actual) Esto es útil cuando el script tiene que ejecutarse en varios entornos donde la ubicación del binario de bash es desconocida, en otras palabras, a través de múltiples plataformas Unix y similares a Unix. Sin embargo, esto hace que la versión real de bash
que interpretará el script sea impredecible.
Por ejemplo, suponga que tiene instalado bash v5 en la configuración por defecto (como /usr/local/bin/bash
. Un script con el shebang #!/usr/bin/env bash
lanzado en el entorno de usuario (es decir, desde Terminal) utilizará el más nuevo bash
, ya que /usr/local/bin
viene antes de /bin
en el orden de búsqueda.
Cuando usted lanza el mismo script en un contexto diferente, por ejemplo, como un script de instalación, un AppleScript, o un sistema de gestión, /usr/local/bin
probablemente no será parte de la PATH
en ese entorno. Entonces el shebang env
elegirá /bin/bash
(v3). El script será interpretado y podría comportarse de manera diferente.
Los administradores prefieren la certeza en sus entornos gestionados. Los administradores deben conocer la ubicación y las versiones de los binarios en sus sistemas. Para los scripts de gestión, debe evitar env
y utilizar la ruta completa adecuada al binario del intérprete deseado.
Las soluciones para resolver la ambigüedad son
- utilizar la ruta completa al binario en el shebang
- gestionar y actualizar la versión adicional personalizada de
bash
con un sistema de gestión - (opcional) renombrar el binario más nuevo de
bash
abash5
obash4
(esto también le permite tenerbash
v4 ybash
v5 disponible en el mismo sistema) - Scripting OS X: En el Shebang
- Scripting OS X: Estableciendo el PATH en los Scripts
Cambiando el Shell por defecto de un usuario a bash v5
Aunque hayamos instalado bash v5, el shell por defecto de una nueva ventana de Terminal seguirá utilizando el bash v3 incorporado.
La ruta del shell por defecto se almacena en el registro del usuario. Puede cambiar directamente el atributo UserShell
con dscl
, en las ‘Opciones Avanzadas’ del panel de preferencias ‘Usuarios & Grupos’, o en la Utilidad de Directorios.
También hay un comando para establecer el shell por defecto:
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin: chsh: /usr/local/bin/bash: non-standard shell
El comando chsh
(cambiar shell) comprobará los shells permitidos en el archivo /etc/shells
. Puedes añadir fácilmente una línea con /usr/local/bin/bash
a este archivo, y entonces chsh
funcionará bien.
$ chsh -s /usr/local/bin/bashChanging shell for armin.Password for armin:
Nota: si eliges cambiar el nombre del binario bash
, tienes que usar el nombre cambiado en /etc/shells
y con chsh
.
Recuerda que el simple hecho de ejecutar chsh
no cambiará el shell en la ventana actual del Terminal. Es mejor cerrar la antigua ventana de Terminal y abrir una nueva para obtener el nuevo shell.
Empaquetando bash v5 para su despliegue masivo
Si bien estos pasos para instalar y configurar bash v5 en un solo Mac son lo suficientemente simples, no funcionarían bien con un sistema de gestión para cientos o miles de Macs. Queremos envolver todos los archivos que make install
crea en una carga útil del instalador de paquetes.
La opción --help
del script configure
arroja esta útil información:
Por defecto,
make install' will install all the files in
/usr/local/bin,
/usr/local/libetc. You can specify an installation prefix other than
/usr/localusing
-prefijo, for instance
-prefijo=$HOME`.
Cuando ejecutamos el script configure con la opción --prefix
crea una carpeta adecuada como carga útil para un instalador de paquetes. Entonces podemos usar pkgbuild
para construir para crear un 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: el argumento --prefix
requiere una ruta absoluta.)
Automatizar la creación del paquete
Así, tenemos nuestro flujo de trabajo para construir un paquete instalador para distribuir y configurar bash v5:
- descargar el archivo
- extraer el archivo
- ejecutar
configure
con el argumento--prefix
- ejecutar
make install
para crear los archivos en una carpeta payload - opcional: renombrar el binario resultante
bash
abash5
para evitar conflictos - añadir un script
postinstall
que añada/usr/local/bin/bash
a/etc/shells
si aún no está presente - construir el instalador con
pkgbuild
Esto suena como un flujo de trabajo maduro para la automatización. Puedes obtener el script de este repositorio.
Puedes pasar un número de versión bash diferente (válido) como argumento al script, por ejemplo 4.4.18
. (No he probado nada significativamente más antiguo.) El script no autodetecta la última versión y por defecto se pasa a la versión 5.0
cuando no se da ningún argumento. Cuando se publique una actualización a bash v5, habrá que modificar la línea de la versión o ejecutar el script con un argumento.
No he averiguado (todavía) cómo detectar la última versión desde la página web de descargas. Una receta autopkg
tendrá que esperar para eso. (Si alguien más quiere abordar eso, por favor, hágalo!)