Общее решение для eval
с правильно заключенными в кавычки аргументами
Следующая функция использует собственный механизм цитирования оболочки, поэтому мне не нужно беспокоиться о том, как правильно заключать в кавычки:
function token_quote {
local quoted=()
for token; do
quoted+=( "$(printf '%q' "$token")" )
done
printf '%s\n' "${quoted[*]}"
}
Пример использования:
$ token_quote token 'single token' token
token single\ token token
Выше обратите внимание, что пробел single token
указан в \
.
$ set $(token_quote token 'single token' token)
$ eval printf '%s\\n' "$@"
token
single token
token
$
Это показывает, чтотокены действительно хранятся отдельно.
Учитывая некоторые ненадежные пользовательские данные:
% input="Trying to hack you; date"
Создайте команду для eval:
% cmd=(echo "User gave:" "$input")
Оцените ее, используя казалось бы правильное цитирование:
% eval "$(echo "${cmd[@]}")"
User gave: Trying to hack you
Thu Sep 27 20:41:31 +07 2018
Обратите внимание, что вас взломали.date
было выполнено, а не напечатано буквально.
Вместо этого с token_quote()
:
% eval "$(token_quote "${cmd[@]}")"
User gave: Trying to hack you; date
%
eval
не зло - это просто неправильно понято:)