@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
}
НИЗ
Теперь у вас все настроено, так что вот где вы будете выполнять и извлекать результаты.
_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%). Эти назначения, например, функции по умолчанию: «Используйте значение по умолчанию, только если ни одно еще не было установлено».