Вот надежная * Bash функция 1002 *, которую, несмотря на использование eval
, следует использовать безопасно.
Все ${varName}
ссылки на переменные во входном тексте расширяются на основе переменных вызывающей оболочки.
Ничего другого не расширен: ни ссылки на переменные, имена которых не заключены в {...}
(например, $varName
), ни замены команд ($(...)
и устаревший синтаксис `...`
), ни арифметические замены ($((...))
и устаревший синтаксис $[...]
).
Чтобы трактовать $
как литерал, \
- уберечь его; e.g.:\${HOME}
Обратите внимание, что ввод принимается только через stdin .
Пример:
$ expandVarsStrict <<<'$HOME is "${HOME}"; `date` and \$(ls)' # only ${HOME} is expanded
$HOME is "/Users/jdoe"; `date` and $(ls)
Исходный код функции:
expandVarsStrict(){
local line lineEscaped
while IFS= read -r line || [[ -n $line ]]; do # the `||` clause ensures that the last line is read even if it doesn't end with \n
# Escape ALL chars. that could trigger an expansion..
IFS= read -r -d '' lineEscaped < <(printf %s "$line" | tr '`([$' '\1\2\3\4')
# ... then selectively reenable ${ references
lineEscaped=${lineEscaped//$'\4'{/\${}
# Finally, escape embedded double quotes to preserve them.
lineEscaped=${lineEscaped//\"/\\\"}
eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
done
}
Функция предполагает, что на входе отсутствуют управляющие символы 0x1
, 0x2
, 0x3
и 0x4
, поскольку эти символы. используются внутренне - поскольку функция обрабатывает text , это должно быть безопасным допущением.