@slm ha già incluso i documenti POSIX - che sono molto utili - ma in realtà non si espandono sul modo in cui questi parametri possono essere combinati per influenzarsi a vicenda. Non c'è ancora alcuna menzione qui di questo modulo:
${var?if unset parent shell dies and this message is output to stderr}
Questo è un estratto di un'altra mia risposta , e penso che dimostri molto bene come funzionano:
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?
Un altro esempio dallo stesso :
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
L'esempio precedente sfrutta tutte e 4 le forme di sostituzione dei parametri POSIX e i loro vari :colon null
o not null
test. Ci sono maggiori informazioni nel link sopra, ed eccolo di nuovo .
Un'altra cosa che la gente spesso non considera ${parameter:+expansion}
è quanto possa essere utile in un documento qui. Ecco un altro estratto da una risposta diversa :
SUPERIORE
Qui imposterai alcune impostazioni predefinite e ti preparerai a stamparle quando viene chiamato ...
#!/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
Qui è dove si definiscono altre funzioni da chiamare sulla funzione di stampa in base ai loro risultati ...
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
}
PARTE INFERIORE
Ora hai tutto configurato, quindi ecco dove eseguirai e tirerai i risultati.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
RISULTATI
Esaminerò il perché tra un momento, ma l'esecuzione di quanto sopra produce i seguenti risultati:
_less_important_function()'s
prima corsa:
Sono andato a casa di tua madre e ho visto Disney on Ice.
Se fai calligrafia avrai successo.
poi _more_important_function():
Sono andato al cimitero e ho visto Disney on Ice.
Se fai matematica correttiva ci riuscirai.
_less_important_function()
ancora:
Sono andato al cimitero e ho visto Disney on Ice.
Se fai matematica correttiva te ne pentirai.
COME FUNZIONA:
La caratteristica chiave qui è il concetto di conditional ${parameter} expansion.
È possibile impostare una variabile su un valore solo se non è impostata o è nulla utilizzando il modulo:
${var_name
: =desired_value}
Se invece desideri impostare solo una variabile non impostata, ometteresti i :colon
valori null e rimarrebbero così come sono.
IN CAMPO DI APPLICAZIONE:
Potresti notare che nell'esempio sopra $PLACE
e $RESULT
essere cambiato quando impostato tramite parameter expansion
anche se _top_of_script_pr()
è già stato chiamato, presumibilmente impostandoli quando viene eseguito. Il motivo per cui funziona è che _top_of_script_pr()
è una ( subshelled )
funzione: l'ho racchiusa in un oggetto parens
anziché { curly braces }
nell'altro. Poiché viene chiamato in una subshell, ogni variabile che imposta è locally scoped
e quando ritorna alla sua shell padre quei valori scompaiono.
Ma quando _more_important_function()
imposta $ACTION
è globally scoped
così influenza la _less_important_function()'s
seconda valutazione di $ACTION
perché _less_important_function()
imposta $ACTION
solo tramite${parameter:=expansion}.
man bash
; cercare il blocco "Parameter Expansion" (circa il 28%). Queste assegnazioni sono ad esempio funzioni predefinite: "Utilizzare il valore predefinito solo se non è stato ancora impostato nessuno".