BASH

Mis notas sobre manejo de la línea de comandos y programación de scripts en el GNU Bourne-Again SHell (BASH).


Índice

  1. Propósito
  2. Instalación y actualización
  3. Digno de mencionarse
  4. Referencias

Propósito

Estuve considerando organizar estas notas de varias formas: de manera similar a algunos libros, igual que la documentación en línea que el mismo BASH provee (man bash), como algunos tutoriales lo presentan, etcétera. Pero, al no tener un plan de obra determinado resulta complicado. Así, baste decir que, salvo por alguna reorganización que se dé en el futuro, por el momento los temas son presentados y organizados esencialmente por afinidad de éstos y mi criterio.

En caso de que algo en esta página o sitio resulte de su interés para ser incluido como referencia, favor de considerar las indicaciones generales que señalo al final de ésta página, así como las recomendaciones sobre citado y atribución. Asimismo, téngase presente la declaración de responsabilidad sobre la información presentada y su utilización.

Instalación y actualización

Las instrucciones de instalación y actualización se han comenzado a organizar en orden de versión descendente (implicando un orden cronológico descendente también).

BASH 5

macOS «Big Sur»

Para esta versión de macOS, para una máquina con M1 y una Intel, el BASH incluido es:

$ bash --version
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin20) Copyright (C) 2007 Free Software Foundation, Inc.

y

% bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)
Copyright (C) 2007 Free Software Foundation, Inc.

el cual no difiere de la versión incluida con «Catalina«. Para la M1 se descargó Xcode 13 y BASH 5.1.8. Para el caso del equipo con Intel, se descargó BASH 5.1.16 y se trabajó con Xcode 13.2.1. Se siguieron las instrucciones de instalación dadas en la sección de «Catalina«.

macOS «Catalina»

Al igual que las versiones predecesoras del sistema operativo, la versión de BASH que se incluye en la versión de macOS 10.15 sigue siendo una muy vieja (y la misma que con «High Sierra«).

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.

y las cosas se complicaron para Apple con cuestiones de licencias, pues BASH ha sido licenciado como GPL v3 desde la versión 4 y Apple no incluye herramientas con licencias GPL v3 con macOS. Buscando repetir la experiencia de instalación de una mejor versión de BASH como lo hice con la versión 4, estoy repitiéndola con la versión 5, buscando ampliar la experiencia.

Antes de iniciar, conviene revisar que se tengan instaladas las herramientas necesarias, en este caso Xcode (instalar las herramientas de línea de comando y aceptar la licencia).

  1. Se descarga desde el sitio del proyecto la última versión de BASH. Al momento de escribir estas notas, del sitio de descarga veo algo lo que muestra la imagen inferior. Se descarga el paquete bash-5.0.tar.gz.
  2. Considerar desde el inicio el que quizás en algún momento se requieran «permisos de administración» para instalar algunas cosas por lo que es recomendable hacer esto desde una cuenta capaz de hacer sudo.
  3. Descargado el paquete y colocado donde uno pueda trabajar, se expande y se cambiar uno al directorio resultante. Yo lo he expandido desde el Finder y movido el directorio generado a un lugar donde pueda trabajar desde Terminal.

    $ cd ~/Downloads/bash-5.0
    $ ./configure
    $ make
    $ sudo make install
  4.  Importante mencionar que el último paso no substituye al bash en /bin, sino que instala el programa generado en /usr/local/bin/bash. En mi instalación PATH es

    $ echo $PATH
    /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Library/Apple/bin

    que uno pensaría es más que suficiente para hacer uso del BASH 5

    $ bash --version
    GNU bash, version 5.0.0(1)-release (x86_64-apple-darwin19.0.0)
    Copyright (C) 2019 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    ...

pero hay que tener presente hacer el registro del nuevo shell. La recomendación es hacerlo para el usuario de trabajo y conservar sin cambio la cuenta de administración del equipo.


$ sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"
$ chsh -s /usr/local/bin/bash usuario

Ahora, con respecto las actualizaciones (parches) de BASH, como se ilustra en el paso 1, en el sitio desde donde se hizo la descarga, pueden verse las actualizaciones de la versión. para instalarlas, se puede proceder de la siguiente forma (al momento de escribir esto, se cuentan 11 parches disponibles, por lo que hay que ajustar el valor en el comando abajo indicado según sea conveniente):

  1. Dentro del directorio donde se descargó inicialmente el paquete (ver pasos previos):
    $ curl 'https://ftp.gnu.org/gnu/bash/bash-5.0-patches/bash50-[001-011]' -O | patch p0
  2. Después de esto, y a diferencia de cuando se compiló por vez primera, esto se reportará al preguntar por la versión de BASH.

    $ bash --version
    GNU bash, version 5.0.0(2)-release (x86_64-apple-darwin19.0.0)
    Copyright (C) 2019 Free Software Foundation, Inc.
    ...

BASH 4

macOS y OS X

Hasta macOS 10.13.6, la versión de BASH distribuida es:

$ bash -version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.

Mavericks

lo que no ha mejorado mucho desde OS X 10.9.5:

$ bash --version
GNU bash, version 3.2.53(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.

esto puede representar incompatibilidades y limitantes si se ha venido desarrollando en algún linux con una versión más reciente (como puede ser el caso de CentOS v7.x), especialmente con alguna versión 4.x, que agrega importantes cambios. Una de estas limitantes es, por ejemplo, la ausencia de arreglos asociativos, disponibles desde BASH v4.0, por lo que la actualización del shell puede ser, más que deseable, una necesidad.

Además de la aquí descrita, es posible instalar el shell empleado un administrador de paquetes como MacPorts y Homebrew. Para los más osados, está la opción de compilación a partir del código fuente1,2, que es la que procedemos a describir de la siguiente forma:

  1. Se descarga la versión deseada del sitio del desarrollador (o algún otro confiable). Para el caso aquí descrito, el código fuente se descargó del sitio de GNU, de donde es posible obtener el la versión actual y previas.
  2. Vía Finder o Terminal, Se desempaca el código.
  3. Se posiciona uno dentro del directorio desempacado, empleando Terminal (los comandos subsecuentes serán ejecutados en la sesión abierta en Terminal).
  4. La versión de BASH incluida por defecto en macOS se encuentra en /bin. La práctica recomendada es no reemplazarloi. Por lo que se debe elegir una ruta alternativa para la instalación de esta actualización. Usualmente /usr/local/bin es lo más adecuado y conviene validar que no exista ya un BASH ahí, cosa que puede hacerse con:

    $ ls /usr/local/bin/b*
    $ more /private/etc/shells

    El resultado de ambos comandos no debe indicar la existencia de un intérprete BASH en la ruta que hemos seleccionado en el paso previo (sólo en caso de que antes no se haya hecho esta instalación, en caso de ser una actualización estos resultados serán positivos).
  5. Se procede con la compilación como se indica a continuación. El resultado quedará en un dirctorio bin dentro de la ruta que indicamos con el parámetro --prefixii.

    $ ./configure --prefix=/usr/local && make && sudo make install

     

    1. Se agrega el nuevo shell a la lista de shells permitidos y, de ser necesario, se modifica el registro del shell designado por defecto para poder usarlo desde la cuenta que así lo requierai. En caso de tratarse de una actualización (el haber hecho ya estos pasos)iii esto no es necesario.

      $ sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"
      $ chsh -s /usr/local/bin/bash usuario
  6. Para validar el funcionamiento del shell, sirve abrir una nueva sesión y probar:

    $ echo $BASH_VERSION
    $ bash --version

Notas

  1. Una práctica de seguridad recomendada es habilitar una cuenta de usuario no privilegiada en el equipo para el trabajo ordinario y cotidiano, y usar una cuenta privilegiada para la administración de éste. Si éste es el caso , entonces lo más recomendable será que el shell BASH original permanezca como el válido para la cuenta administrativa del equipo y habilitar el que estamos instalando aquí para esa o esas otras cuentas para actividades diarias y ordinarias.
  2. En su página de gist en GitHub, Samnang Chhun2, indica como valor del parámetro –prefix la cadena /usr/local/bin. El valor correcto debe ser /usr/local ya que el script de compilación agrega ya el subdirectorio bin al valor dado. De no existir un archivo de nombre bash en /usr/local/bin, el comando chsh -s /usr/local/bin/bash indicado más adelante en su página marcará un error, y de existir será aplicado a esa versión previa.
  3. Estas instrucciones fueron elaboradas al instalar la versión 4.4.0 y han sido revisadas al actualizarla a la versión 4.4.18. Correcciones y mejoras han sido hechas al texto, las acciones permanecen sin cambio.

Digno de mencionarse

Algunas rarezas, extrañezas, maravillas o particularidades poco conocidas o que me han sorprendido de este shell o de alguna dev sus versiones. También, ejemplo de código o implementación de ideas.

  • Al redireccionar la salida a una variable, y luego imprimirla (echo), los line feed no aparecen a menos que la variable sea colocada entre comillas.
  • Un pipe está compuesto de subshells transitorios, por lo que el valor que a una variable (creada en el pipe o usada en éste) se perderá a menos que se activa la opción shopt -s lastpipe.
  • Para evitar borrar pero también que se ejecute, como indica el manual, la combinación de la meta tecla y # permite comentar la línea de comando actual insertando el carater # al inicio. En una mac presionar Esc liberar y a continuación Shift + 3.

Buenas prácticas y convenciones

Por convención:

  • Nombres de variables deben estar en minúsculas, a menos que representen variables de entorno o componentes integrados de shell.

Buenas prácticas:

  • Sigue las convenciones al elaborar scripts. Ya sea las establecidas por tu grupo de trabajo pero mejor si son las estándares; lo importante es ser uniforme en un tipo de codificación.

PS1

Las secuencias de escape no imprimibles (non-printing escape sequence), \[ and \] solo se emplean con el prompt PS1. No incluirlas trae problemas de posicionamiento del cursor, especialmente cuando se revisa la historia de comandos introducidos4.

Repeat…until

Ejecución previa del código de ruptura del ciclo

actions() {
   check_if_file_present
   # Do other stuff
}

actions #1st execution
while [ current_time <= $cutoff ]; do
   actions # Loop execution
done

o

while : ; do
    actions
    [[ current_time <= $cutoff ]] || break
done

Adiciones

brew install tree

Referencias

  1. Ian McCracken, «Upgrade bash to 4.0 in Mac OS X«, Concision and Concinnity, blog; posted: 2009.03.09, consulted: 2016.06.06. URL: http://concisionandconcinnity.blogspot.mx/2009/03/upgrade-bash-to-40-in-mac-os-x.html.
  2. «Install Bash version 4 on MacOS X«, GitHubGist, web. Retrieved: 2018.10.28. URL: https://gist.github.com/samnang/1759336.
  3. Pete Brown, «Fun with the Windows Subsystem for Linux«, Microsoft, blog; published: 2016.07.22, consulted: 2016.07.28. URL: https://blogs.windows.com/buildingapps/2016/07/22/fun-with-the-windows-subsystem-for-linux
  4. «Non-printing escape sequence: when?«, stackexchange.com, Unix & Linux forum, web. Asked: 2014.09.27; visited: 2022.08.08. URL: https://unix.stackexchange.com/questions/157878/non-printing-escape-sequence-when.

Twitter Wordpress eMail
© Todos los derechos reservados.
Dr. Eduardo René Rodríguez Avila
Creación: 2016.06.05
Última actualización: 2022.08.30
El contenido de este sitio puede ser copiado y reproducido libremente mientras no sea alterado y se cite su origen. Marcas y productos registrados son citados por referencia y sin fines de lucro o dolo. Todas las opiniones son a título personal del o los autores de éstas y, salvo sea expresado de otro modo, deben considerarse como registro y expresión de la experiencia de uso de aquello que es tratado. Para conocer más sobre la posición de privacidad y responsabilidad de lo que se presenta en este sitio web y como ha sido obtenido, consulte la declaración al respecto.