eval: почему опасен и когда реально нуженВ Bash почти любую строку можно превратить в команду через
eval. Он берёт переданный текст и запускает его как новый Bash-код.Именно поэтому это один из самых спорных инструментов в shell-скриптах.
▪️Как работает
evalПростой пример:
cmd="ls -la"
eval "$cmd"
Bash сначала получает строку:
ls -la
а затем выполняет её как обычную команду.
▪️Где возникает проблема
Если данные приходят от пользователя:
read inputeval "$input"
Теперь введённый текст становится кодом.
Например, вместо ожидаемого аргумента можно передать дополнительные команды, которые Bash выполнит при обработке строки.
Главная проблема
eval - повторный разбор данных как команд.▪️Почему кавычки не всегда спасают
Например:
file="test.txt"
eval "cat $file"
Пока значение простое - всё работает.
Но если внутри появятся специальные символы:
file="file name.txt"или другие управляющие конструкции, поведение может отличаться от ожидаемого.
▪️Частая замена
evalВместо хранения команды строкой:
cmd="ls -la /tmp"
eval "$cmd"
лучше использовать массив:
cmd=(ls -la /tmp)
"${cmd[@]}"
Теперь Bash хранит команду и аргументы отдельно.
▪️Когда
eval действительно нуженИногда без него сложно обойтись. Например, при работе с динамическими именами переменных:
name="USER"eval "echo \$$name"
Но даже здесь часто есть более безопасные варианты:
declare -n ref="$name"
echo "$ref"
▪️Проверка перед использованием
Если всё же нужен
eval, данные должны быть полностью контролируемыми:case "$action" in
start|stop|restart)
eval "service_$action"
;;
esac
Здесь значение ограничено заранее известным списком.
▪️Почему это важно
eval не является “плохой” командой сам по себе. Проблема появляется, когда данные превращаются в код.В большинстве случаев массивы,
case, функции или declare решают задачу безопаснее. eval стоит оставлять только для ситуаций, где действительно нужен второй проход парсинга Bash.BashTex 📱 #eval