@slm ya ha incluido los documentos POSIX , que son muy útiles, pero en realidad no amplían la forma en que estos parámetros se pueden combinar para afectarse entre sí. Todavía no hay ninguna mención aquí de este formulario:
${var?if unset parent shell dies and this message is output to stderr}
Este es un extracto de otra respuesta mía, y creo que demuestra muy bien cómo funcionan:
sh <<-\CMD
_input_fn() { set -- "$@" #redundant
echo ${*?WHERES MY DATA?}
#echo is not necessary though
shift #sure hope we have more than $1 parameter
: ${*?WHERES MY DATA?} #: do nothing, gracefully
}
_input_fn heres some stuff
_input_fn one #here
# shell dies - third try doesnt run
_input_fn you there?
# END
CMD
heres some stuff
one
sh: line :5 *: WHERES MY DATA?
Otro ejemplo de lo mismo :
sh <<-\CMD
N= #N is NULL
_test=$N #_test is also NULL and
v="something you would rather do without"
( #this subshell dies
echo "v is ${v+set}: and its value is ${v:+not NULL}"
echo "So this ${_test:-"\$_test:="} will equal ${_test:="$v"}"
${_test:+${N:?so you test for it with a little nesting}}
echo "sure wish we could do some other things"
)
( #this subshell does some other things
unset v #to ensure it is definitely unset
echo "But here v is ${v-unset}: ${v:+you certainly wont see this}"
echo "So this ${_test:-"\$_test:="} will equal NULL ${_test:="$v"}"
${_test:+${N:?is never substituted}}
echo "so now we can do some other things"
)
#and even though we set _test and unset v in the subshell
echo "_test is still ${_test:-"NULL"} and ${v:+"v is still $v"}"
# END
CMD
v is set: and its value is not NULL
So this $_test:= will equal something you would rather do without
sh: line 7: N: so you test for it with a little nesting
But here v is unset:
So this $_test:= will equal NULL
so now we can do some other things
_test is still NULL and v is still something you would rather do without
El ejemplo anterior aprovecha las 4 formas de sustitución de parámetros POSIX y sus diversas :colon null
o not null
pruebas. Hay más información en el enlace de arriba, y aquí está de nuevo .
Otra cosa que la gente a menudo no considera ${parameter:+expansion}
es cuán útil puede ser en un documento aquí. Aquí hay otro extracto de una respuesta diferente :
PARTE SUPERIOR
Aquí establecerá algunos valores predeterminados y se preparará para imprimirlos cuando se llame ...
#!/bin/sh
_top_of_script_pr() (
IFS="$nl" ; set -f #only split at newlines and don't expand paths
printf %s\\n ${strings}
) 3<<-TEMPLATES
${nl=
}
${PLACE:="your mother's house"}
${EVENT:="the unspeakable."}
${ACTION:="heroin"}
${RESULT:="succeed."}
${strings:="
I went to ${PLACE} and saw ${EVENT}
If you do ${ACTION} you will ${RESULT}
"}
#END
TEMPLATES
MEDIO
Aquí es donde define otras funciones para llamar a su función de impresión en función de sus resultados ...
EVENT="Disney on Ice."
_more_important_function() { #...some logic...
[ $((1+one)) -ne 2 ] && ACTION="remedial mathematics"
_top_of_script_pr
}
_less_important_function() { #...more logic...
one=2
: "${ACTION:="calligraphy"}"
_top_of_script_pr
}
FONDO
Ya lo tiene todo configurado, así que aquí es donde ejecutará y extraerá sus resultados.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
RESULTADOS
Analizaré por qué en un momento, pero ejecutar lo anterior produce los siguientes resultados:
_less_important_function()'s
primer intento:
Fui a la casa de tu madre y vi Disney on Ice.
Si haces caligrafía tendrás éxito.
entonces _more_important_function():
Fui al cementerio y vi Disney on Ice.
Si haces matemáticas correctivas tendrás éxito.
_less_important_function()
de nuevo:
Fui al cementerio y vi Disney on Ice.
Si haces matemáticas correctivas te arrepentirás.
CÓMO FUNCIONA:
La característica clave aquí es el concepto de conditional ${parameter} expansion.
Puede establecer una variable en un valor solo si no está establecida o es nula utilizando el formulario:
${var_name
: =desired_value}
Si, en cambio, desea establecer solo una variable no establecida, omitirá los :colon
valores nulos y permanecerá como está.
EN ALCANCE:
Puede notar eso en el ejemplo anterior $PLACE
y $RESULT
cambiarlo cuando se configura a través de parameter expansion
aunque _top_of_script_pr()
ya se haya llamado, presumiblemente configurándolos cuando se ejecuta. La razón por la que esto funciona es que _top_of_script_pr()
es una ( subshelled )
función: la incluí en parens
lugar de la { curly braces }
utilizada para los demás. Debido a que se llama en una subshell, cada variable que establece es locally scoped
y cuando regresa a su shell principal esos valores desaparecen.
Pero cuando se _more_important_function()
establece $ACTION
es globally scoped
así, afecta a la _less_important_function()'s
segunda evaluación de $ACTION
porque _less_important_function()
establece $ACTION
solo a través de${parameter:=expansion}.
man bash
; busque el bloque "Expansión de parámetros" (aproximadamente el 28%). Estas asignaciones son, por ejemplo, funciones predeterminadas: "Use el valor predeterminado solo si aún no se ha configurado ninguno".