Мне нравятся вспомогательные функции, чтобы скрыть грубые детали bash В этом случае это добавляет еще больше (скрытой) грубости:
# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
local varname="$1"
! [ -z ${!varname+x} ]
}
Поскольку у меня впервые были ошибки в этой реализации (вдохновленные ответами Дженса и Лайонела), я пришел к другому решению:
# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
declare -p $1 &>/dev/null
}
Я считаю, что это более прямолинейно, более застенчиво и легче для понимания / запоминания. Тестовый пример показывает, что это эквивалентно:
function main()
{
declare -i xyz
local foo
local bar=
local baz=''
IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"
IsDeclared xyz; echo "IsDeclared xyz: $?"
IsDeclared foo; echo "IsDeclared foo: $?"
IsDeclared bar; echo "IsDeclared bar: $?"
IsDeclared baz; echo "IsDeclared baz: $?"
}
main
Тестовый пример также показывает, что local var
действительно НЕ объявляет var (если не следует '='). В течение довольно долгого времени я думал, что я объявил переменные таким образом, просто чтобы теперь обнаружить, что я просто выразил свое намерение ... это неоперация, я думаю.
IsDeclared_Tricky xyz: 1
IsDeclared_Tricky foo: 1
IsDeclared_Tricky bar: 0
IsDeclared_Tricky baz: 0
IsDeclared XYZ: 1
IsDeclared foo: 1
IsDeclared bar: 0
IsDeclared baz: 0
БОНУС: usecase
В основном я использую этот тест, чтобы задавать (и возвращать) параметры для функций несколько"элегантно" и безопасно (почти как интерфейс ...):
#auxiliary functions
function die()
{
echo "Error: $1"; exit 1
}
function assertVariableDeclared()
{
IsDeclared "$1" || die "variable not declared: $1"
}
function expectVariables()
{
while (( $# > 0 )); do
assertVariableDeclared $1; shift
done
}
# actual example
function exampleFunction()
{
expectVariables inputStr outputStr
outputStr="$inputStr world!"
}
function bonus()
{
local inputStr='Hello'
local outputStr= # remove this to trigger error
exampleFunction
echo $outputStr
}
bonus
Если вызывается со всеми объявленными переменными:
Привет, мир!
еще:
Ошибка: переменная не объявлена: outputStr