Asignación de valores predeterminados a variables de shell con un solo comando en bash


682

Tengo un montón de pruebas en variables en un script de shell bash (3.00) donde si la variable no está configurada, entonces asigna un valor predeterminado, por ejemplo:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

Creo recordar que hay una sintaxis para hacer esto en una línea, algo parecido a un operador ternario, por ejemplo:

FOO=${ ${VARIABLE} : 'default' }

(aunque sé que eso no funcionará ...)

¿Estoy loco o existe algo así?


1
La sección de expansión de parámetros de Shell de la referencia de shell de bash es un buen punto de partida: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou

1
Documentación de Gnu.org para Shell Parameter Expansion (pista: ¡hay muchas otras cosas geniales que puedes hacer!)
JDB todavía recuerda a Monica el

Respuestas:


1226

Muy cerca de lo que publicaste, en realidad:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

O, lo que va a asignar defaulta VARIABLEasí:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.

64
Si quisiera encontrar esto en la documentación, ¿para qué sería un google? Buscar en Google con caracteres especiales como $ {: -} no es muy fácil.
Joshua Olson el

20
En respuesta a solarmist: "la asignación predeterminada de la variable bash" me dejó en esta página, y la búsqueda en la página del manual de bash con 'variable ass' me llevó a la sección correcta después de ~ cinco 'next'
Mooshu

57
Tenga en cuenta que es no específica de Bash y trabajará con el conjunto de concha familia. Es seguro para scripts genéricos.
Jocelyn delalande

16
@solarmist La palabra clave es "expansión de parámetros bash", si desea obtener más información sobre él y sus acompañantes.
duleshi

20
Aquí hay una explicación más detallada sobre el tema unix.stackexchange.com/a/122848/2407
jottr

289

Para argumentos de línea de comando:

VARIABLE=${1:-DEFAULTVALUE}    

que se asigna al VARIABLEvalor del primer argumento pasado al script o al valor de DEFAULTVALUEsi no se pasó dicho argumento.


244

Si la variable es la misma, entonces

: "${VARIABLE:=DEFAULT_VALUE}"

asigna DEFAULT_VALUE a VARIABLE si no está definido. Las comillas dobles evitan el engorde y la división de palabras.

Consulte también la Sección 3.5.3, Expansión del parámetro Shell , en el manual de Bash.


27
Este truco complicado no era obvio para mí, usando: sin efecto incorporado para comer la expansión del $ {..} PERO dejando el conjunto VARIABLE. Hasta ahora estaba haciendo esto: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" y me sentía tonto por usar VARIABLE dos veces.
Dino

Resulta que ESTO NO FUNCIONA SIEMPRE PARA VARIABLES DE BASH-BUILTIN. Es muy muy raro. Actualmente, los que HISTTIMEFORMAT
conozco

¿Cómo establecería múltiples valores predeterminados? Intenté ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" pero eso no parece funcionar ...
Hans

8
@Hans: los dos puntos son el comando (que no hace nada) y, por lo tanto, solo se necesitan una vez. Ej .: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik

35

Incluso puedes usar como valor predeterminado el valor de otra variable

tener un archivo defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

ejecutar ./defvalue.sh first-value second-valuesalida

first-value
second-value

y ejecutar ./defvalue.sh first-valuesalida

first-value
first-value

28

ver aquí en 3.5.3 (expansión de parámetros de shell)

entonces en tu caso

${VARIABLE:-default}

26

Para responder a su pregunta y en todas las sustituciones variables

echo "$\{var}"
echo "Substitute the value of var."


echo "$\{var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."


echo "$\{var:=word}"
echo "If var is null or unset, var is set to the value of word."


echo "$\{var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."


echo "$\{var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."

18

FWIW, puede proporcionar un mensaje de error como este:

USERNAME=${1:?"Specify a username"}

Esto muestra un mensaje como este y sale con el código 1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

Un ejemplo más completo de todo:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

Salida:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION toma el valor del primer argumento y sale si está vacío
  • $DIRNAME es el segundo argumento y su valor predeterminado es el directorio actual
  • $OUTPUT_DIRes la tercera discusión, o $HOMEDIR(si está definida), de lo contrario, /tmp. Esto funciona en OS X, pero no estoy seguro de que sea portátil.

17

Luego está la forma de expresar su construcción 'if' de manera más escueta:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

10

Aquí hay un ejemplo

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

guarde esto como script.sh y hágalo ejecutable. ejecutarlo sin params

./script.sh
> value: [default_value]

ejecutarlo con param

./script.sh my_value
> value: [my_value]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.