O @slm já incluiu os documentos POSIX - que são muito úteis -, mas eles não expandem realmente como esses parâmetros podem ser combinados para afetar um ao outro. Ainda não há menção aqui deste formulário:
${var?if unset parent shell dies and this message is output to stderr}
Este é um trecho de outra resposta minha, e acho que demonstra muito bem como isso funciona:
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?
Outro exemplo do mesmo :
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
O exemplo acima aproveita todas as quatro formas de substituição de parâmetro POSIX e seus vários :colon null
ou not null
testes. Há mais informações no link acima e aqui está novamente .
Outra coisa que as pessoas geralmente não consideram ${parameter:+expansion}
é o quão útil pode ser em um documento aqui. Aqui está outro trecho de uma resposta diferente :
TOPO
Aqui você definirá alguns padrões e se preparará para imprimi-los quando chamados ...
#!/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
MEIO
É aqui que você define outras funções para chamar sua função de impressão com base em seus 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
}
INFERIOR
Agora você tem tudo configurado, então aqui é onde você executa e obtém seus resultados.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
RESULTADOS
Vou explicar o porquê daqui a pouco, mas a execução do procedimento acima produz os seguintes resultados:
_less_important_function()'s
Primeira corrida:
Fui à casa de sua mãe e vi Disney on Ice.
Se você fizer caligrafia você terá sucesso.
então _more_important_function():
Fui ao cemitério e vi Disney on Ice.
Se você praticar matemática corretiva, terá sucesso.
_less_important_function()
novamente:
Fui ao cemitério e vi Disney on Ice.
Se você pratica matemática corretiva, vai se arrepender.
COMO FUNCIONA:
O principal recurso aqui é o conceito de conditional ${parameter} expansion.
Você pode definir uma variável para um valor somente se estiver desconfigurada ou nula usando o formulário:
${var_name
: =desired_value}
Se, em vez disso, você desejar definir apenas uma variável não configurada, você omitirá os :colon
valores nulos e permanecerá como está.
NO ÂMBITO DE APLICAÇÃO:
Você pode perceber isso no exemplo acima $PLACE
e $RESULT
ser alterado quando definido via parameter expansion
mesmo que _top_of_script_pr()
já tenha sido chamado, presumivelmente configurando-os quando é executado. A razão pela qual isso funciona é que _top_of_script_pr()
é uma ( subshelled )
função - eu a incluí em parens
vez da { curly braces }
usada para as outras. Como é chamado em um subshell, todas as variáveis que ele define são locally scoped
e, quando retornam ao shell pai, esses valores desaparecem.
Mas quando _more_important_function()
conjuntos $ACTION
, globally scoped
isso afeta a _less_important_function()'s
segunda avaliação, $ACTION
porque _less_important_function()
conjuntos $ACTION
somente via${parameter:=expansion}.
man bash
; procure o bloco "Expansão de parâmetros" (em cerca de 28%). Essas atribuições são, por exemplo, funções padrão: "Use o valor padrão apenas se ainda não houver nenhum valor definido".