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í?

Edward Q. Bridges
fuente
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.
Andrew McGregor
fuente
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.

miku
fuente
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.

Hans Ginzel
fuente
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
Montells
fuente
28

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

entonces en tu caso

${VARIABLE:-default}
ghostdog74
fuente
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."
Gurú
fuente
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.
Curtis Mattoon
fuente
17

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

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}
Rob Wells
fuente
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]
Assaf Shomer
fuente