Оскільки я сприймаю ваше значення, я не вважаю, що будь-яка з цих відповідей є правильною. 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
}
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}.
:НУЛЬ
І чому я використовую провідний :colon?
Ну, на man
сторінці буде сказано, що : does nothing, gracefully.
Ви бачите, parameter expansion
саме так воно і звучить - це expands
значення Значення. ${parameter}.
Отже, коли ми встановлюємо змінну, ${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.
So, декларування змінної у документі here-document
може працювати, але лише через те, expansion
що обмежує встановлення лише змінних, які вже не встановлені. Однак це абсолютно відповідає вашим потребам так, як ви їх описали, оскільки значення за замовчуванням завжди будуть встановлені під час виклику функції друку шаблону.
ЧОМУ НІ eval?
Що ж, приклад, який я представив, пропонує безпечний та ефективний спосіб прийняття, parameters.
оскільки він обробляє область, кожна змінна, що знаходиться в наборі через ${parameter:=expansion}
, визначається ззовні. Отже, якщо ви помістите все це в сценарій під назвою template_pr.sh і запустили:
% RESULT=something_else template_pr.sh
Ви отримаєте:
Я зайшов до будинку вашої матері і побачив Діснея на льоду
Якщо ви зробите каліграфію, ви будете щось_забагато
Я пішов на кладовище і побачив Діснея на льоду
Якщо ви займаєтеся корекційною математикою, ви будете щось цікавіти
Я пішов на кладовище і побачив Діснея на льоду
Якщо ви займаєтеся корекційною математикою, ви будете щось цікавіти
Це не буде працювати для тих змінних , які були буквально встановлені в сценарії, такі як $EVENT, $ACTION,
і , $one,
але я тільки певних тем , таким чином , щоб продемонструвати різницю.
У будь-якому випадку, прийняття невідомого вводу у evaled
виписку за своєю суттю є небезпечним, тоді parameter expansion
як розроблено спеціально для цього.