@slm вже включив документи POSIX - які дуже корисні - але вони не дуже розширюються щодо того, як ці параметри можна комбінувати, щоб впливати один на одного. Тут ще немає жодної згадки про цю форму:
${var?if unset parent shell dies and this message is output to stderr}
Це уривок з іншої моєї відповіді, і я думаю, що це дуже добре демонструє, як вони працюють:
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?
Ще один приклад з того ж :
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
У наведеному вище прикладі використовуються всі 4 форми заміни параметрів POSIX та їх різні :colon null
або not null
тести. Більше інформації за посиланням вище, і ось воно знову .
Інша річ, про яку люди часто не замислюються, ${parameter:+expansion}
це те, наскільки це може бути дуже корисним у цьому документі. Ось ще один уривок з іншої відповіді :
ТОП
Тут ви встановите деякі параметри за замовчуванням і підготуєтесь до друку, коли їх буде викликано ...
#!/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
СРЕДНІЙ
Тут ви визначаєте інші функції для використання функції друку на основі їх результатів ...
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
}
BOTTOM
Зараз у вас все налаштовано, тому ось, де ви будете виконувати та виводити свої результати.
_less_important_function
: "${PLACE:="the cemetery"}"
_more_important_function
: "${RESULT:="regret it."}"
_less_important_function
РЕЗУЛЬТАТИ
Я розберуся чомусь, але запустивши вище, можна отримати такі результати:
_less_important_function()'s
перший запуск:
Я зайшов до будинку вашої матері і побачив Діснея на льоду.
Якщо ви зробите каліграфію, ви досягнете успіху.
тоді _more_important_function():
Я пішов на кладовище і побачив Діснея на льоду.
Якщо ви займаєтеся корекційною математикою, ви досягнете успіху.
_less_important_function()
знову:
Я пішов на кладовище і побачив Діснея на льоду.
Якщо ви займаєтеся корекційною математикою, ви пошкодуєте про це.
ЯК ЦЕ ПРАЦЮЄ:
Ключовою особливістю тут є концепція conditional ${parameter} expansion.
Ви можете встановити змінну до значення лише у тому випадку, якщо вона не встановлена чи недійсна за допомогою форми:
${var_name
: =desired_value}
Якщо замість цього ви хочете встановити лише незмінену змінну, ви опустите значення :colon
та null, які залишаться такими, які є.
НА ОБЛАСТІ:
Ви можете помітити , що в наведеному вище прикладі $PLACE
і $RESULT
переодягатися при установці з допомогою , parameter expansion
навіть якщо _top_of_script_pr()
вже були викликані, ймовірно , встановивши їх , коли він запущений. Причина цього працює в тому, що _top_of_script_pr()
це ( subshelled )
функція - я вклав її, parens
а не { curly braces }
використовував для інших. Оскільки він викликається в підклітині, кожна змінна, яку він встановить, є, locally scoped
і коли вона повертається до батьківської оболонки, ці значення зникають.
Але коли _more_important_function()
встановлено $ACTION
це globally scoped
так, це впливає на _less_important_function()'s
другу оцінку, $ACTION
оскільки _less_important_function()
встановлює $ACTION
лише через${parameter:=expansion}.
man bash
; пошук блоку "Розширення параметрів" (приблизно на 28%). Це призначення, наприклад, функції за замовчуванням: "Використовуйте значення за замовчуванням, тільки якщо жодне ще не встановлено."