Uso de: – (punto de dos puntos) en bash

¿Cuál es el significado de este estilo en bash?

${PUBLIC_INTERFACE:-eth0} 

¿Cuál es el propósito de :- ?

Si $PUBLIC_INTERFACE existe y no es nulo, devuelva su valor; de lo contrario, devuelva "eth0" .

De hecho, hay algunos de estos documentados en la página de bash man :

$ {parameter: -word} Usar valores predeterminados. Si el parámetro está desactivado o nulo, la expansión de la palabra se sustituye. De lo contrario, el valor del parámetro es sustituido.

$ {parameter: = word} Asignar valores predeterminados. Si el parámetro está desactivado o es nulo, la expansión de la palabra se asigna al parámetro. El valor del parámetro se sustituye. Los parámetros de posición y los parámetros especiales no se pueden asignar de esta manera.

$ {parameter:? word} Muestra error si es nulo o no. Si el parámetro es nulo o no está configurado, la expansión de la palabra (o un mensaje a ese efecto si la palabra no está presente) se escribe en el error estándar y el shell, si no es interactivo, se cierra. De lo contrario, el valor del parámetro es sustituido.

$ {parámetro: + palabra} Usar valor alternativo. Si el parámetro es nulo o no está configurado, no se sustituye nada; de lo contrario, se sustituye la expansión de la palabra.

:- se usa en la expansión del parámetro de shell ${ parameter :- word } : si el parameter es nulo o no está configurado, se expande al valor de word , de lo contrario al valor de parameter .

Ejemplo:

 $ str= $ echo "${str:-default}" default 

Esto y las expansiones similares usando := :+ y :? todos vienen en dos sabores: con y sin dos puntos. La diferencia es que la expansión con el colon comienza por “nulo o no establecido “, mientras que sin los dos puntos, es simplemente “nulo”.

Observar:

 $ str= # Null, but not unset $ echo "${str-default}" # Expands to value of $str, the empty string $ echo "${str:-default}" # Expands to "default" default 

¿Dónde es esto útil? Algunos ejemplos:

  • Valores predeterminados

    • El editor invocado para editar el último comando con fc es el resultado de la expansión ${FCEDIT:-${EDITOR:-vi}} : $FCEDIT si está definido, o bien $EDITOR si está definido, o bien vi .
    • Un bucle en una secuencia de comandos que debe leer de un archivo si se proporciona como argumento y de entrada estándar, de lo contrario podría ser así:

       while IFS= read -r line; do # do something done < "${1:-/dev/stdin}" 
  • Al usar el set -u

    set -u es una forma práctica de forzar scripts más limpios haciendo que el script muera cuando se encuentra con una variable no definida, como lo promueve, por ejemplo, este artículo (no es que respalde todo lo que hay allí 1 ). Si queremos verificar si una cierta variable tiene un valor con [[ $var ]] , la secuencia de comandos ahora muere si var está desarmada, aunque esto sea legítimo.

    La forma de evitar esto es usar [[ ${var:-} ]] lugar, y set -u no se quejará. (Esto es básicamente utilizar un valor predeterminado de nuevo, pero el valor sustituido es la cadena vacía en este caso).

Por cierto, estas expansiones no son exclusivas de Bash: la especificación de shell POSIX también las tiene todas.


1 Véase también BashFAQ / 112, ¿Cuáles son las ventajas y desventajas de usar set -u (o set -o nounset )?