Поскольку я понимаю ваше значение, я не верю, что какой-либо из этих ответов является правильным. eval
в этом нет необходимости, и вам даже не нужно даже дважды оценивать ваши переменные.
Это правда, @Gilles подходит очень близко, но он не рассматривает проблему возможного переопределения значений и того, как они должны использоваться, если они вам нужны более одного раза. В конце концов, шаблон должен использоваться более одного раза, верно?
Я думаю, важен порядок, в котором вы оцениваете их. Учтите следующее:
ВЕРХ
Здесь вы установите некоторые значения по умолчанию и подготовитесь распечатать их при вызове ...
#!/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}.
:ЗНАЧЕНИЕ NULL
И почему я использую ведущий :colon?
Ну, man
страница скажет вам, что : does nothing, gracefully.
вы видите, parameter expansion
это именно то, на что это похоже - это expands
значение ${parameter}.
So. Когда мы устанавливаем переменную с, ${parameter:=expansion}
мы остаемся с ее значением - что оболочка будет попытка выполнить в строке. Если бы он попытался запустить, the cemetery
он бы просто наплевал на вас. PLACE="${PLACE:="the cemetery"}"
будет давать те же результаты, но это также избыточно в этом случае, и я предпочел, чтобы оболочка: ${did:=nothing, gracefully}.
Это позволяет вам сделать это:
echo ${var:=something or other}
echo $var
something or other
something or other
ЗДЕСЬ-ДОКУМЕНТЫ
И, между прочим, встроенное определение нулевой или неустановленной переменной также является причиной того, что работает следующее:
<<HEREDOC echo $yo
${yo=yoyo}
HEREDOC
yoyo
Лучший способ думать об этом here-document
- это фактический файл, переданный во входной дескриптор файла. Более или менее это то, чем они являются, но разные оболочки реализуют их немного по-разному.
В любом случае, если вы не заключите в кавычки значение, <<LIMITER
вы получите его в потоковом режиме и оцените таким expansion.
образом. Объявление переменной в банке here-document
может сработать, но только с помощью expansion
которой вы ограничиваете установку только тех переменных, которые еще не установлены. Тем не менее, это идеально соответствует вашим потребностям, как вы их описали, поскольку ваши значения по умолчанию всегда будут установлены при вызове функции печати шаблона.
ПОЧЕМУ НЕТ eval?
Хорошо, пример, который я представил, предоставляет безопасные и эффективные средства принятия. parameters.
Поскольку он обрабатывает область действия, каждая переменная в наборе via ${parameter:=expansion}
может быть определена извне. Итак, если вы поместите все это в скрипт с именем template_pr.sh и запустите:
% RESULT=something_else template_pr.sh
Вы получите:
Я пошел в дом твоей матери и увидел Диснея на льду
Если вы будете заниматься каллиграфией, то будете
Я пошел на кладбище и увидел Дисней на льду
Если вы делаете корректирующую математику, вы будете что-то
Я пошел на кладбище и увидел Дисней на льду
Если вы делаете корректирующую математику, вы будете что-то
Это не будет работать для тех переменных , которые были буквально установлены в сценарии, такие как $EVENT, $ACTION,
и , $one,
но я только определенных тем , таким образом , чтобы продемонстрировать разницу.
В любом случае принятие неизвестных входных данных в evaled
утверждение по своей сути небезопасно, тогда как parameter expansion
оно специально предназначено для этого.