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 a bash5 o bash4 (esto también le permite tener bash v4 y bash 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 configurecon el argumento --prefix
  • ejecutar make installpara crear los archivos en una carpeta payload
  • opcional: renombrar el binario resultante bash a bash5 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!)

Deja una respuesta

Tu dirección de correo electrónico no será publicada.