Что можно сделать с помощью команды eval
? Почему она полезна? Является ли она какой-то встроенной функцией в bash? Для нее нет страницы man
...
eval
является частью POSIX. Это интерфейс, который может быть встроенным в оболочку.
Он описан в "POSIX Programmer's Manual": http://www.unix.com/man-page/posix/1posix/eval/.
eval - construct command by concatenating arguments
Она принимает аргумент и строит из него команду, которая будет выполнена оболочкой. Вот пример manpage:
1) foo=10 x=foo
2) y='$'$x
3) echo $y
4) $foo
5) eval y='$'$x
6) echo $y
7) 10
$foo
со значением '10'
и $x
со значением 'foo'
.$y
, который состоит из строки '$foo'
. Знак доллара должен быть экранирован
с помощью '$'
.echo $y
.'$foo'
.eval
. Сначала он оценит $x
в строку 'foo'
. Теперь у нас есть оператор y=$foo
, который будет оценен в y=10
.echo $y
теперь будет значение '10'
.Это обычная функция во многих языках, например, в Perl и JavaScript. Посмотрите примеры в perldoc eval: http://perldoc.perl.org/functions/eval.html.
Да, eval
- это внутренняя команда bash, поэтому она описана на странице руководства bash
.
eval [arg ...]
The args are read and concatenated together into a single com-
mand. This command is then read and executed by the shell, and
its exit status is returned as the value of eval. If there are
no args, or only null arguments, eval returns 0.
Обычно она используется в сочетании с Command Substitution. Без явного eval
оболочка пытается выполнить результат подстановки команды, а не оценить его.
Скажем, вы хотите написать эквивалент VAR=value; echo $VAR
. Обратите внимание на разницу в том, как оболочка обрабатывает запись echo VAR=value
:
andcoz@...:~> $( echo VAR=value )
bash: VAR=value: команда не найдена
andcoz@...:~> echo $VAR
<пустая строка>
Оболочка пытается выполнить echo
и VAR=value
как две отдельные команды. Выдается ошибка относительно второй строки. Присвоение остается неэффективным.
2.
andcoz@...:~> eval $( echo VAR=value )
andcoz@...:~> echo $VAR
значение
Оболочка объединяет (конкатенирует) две строки echo
и VAR=value
, разбирает это единое целое по соответствующим правилам и выполняет его.
И последнее, но не менее важное: eval
может быть очень опасной командой. Любой ввод команды eval
должен быть тщательно проверен, чтобы избежать проблем с безопасностью.
У eval
нет man-страницы, потому что это не отдельная внешняя команда, а скорее встроенная в оболочку, то есть команда, внутренняя для оболочки (bash
) и известная только ей. Соответствующая часть страницы руководства bash
гласит:
eval [arg ...]
The args are read and concatenated together into a single command.
This command is then read and executed by the shell, and its exit
status is returned as the value of eval. If there are no args, or only
null arguments, eval returns 0
Кроме того, вывод команды help eval
следующий:
eval: eval [arg ...]
Execute arguments as a shell command.
Combine ARGs into a single string, use the result as input to the shell,
and execute the resulting commands.
Exit Status:
Returns exit status of command or success if command is null.
eval
- мощная команда, и если вы собираетесь ее использовать, то должны быть очень осторожны, чтобы предотвратить возможные риски безопасности, которые с ней связаны.
Выражение eval рассказывает оболочки, чтобы принять аргументы ивала в команды и запускать их через командную строку. Это полезно в ситуации, как показано ниже:
В вашем скрипте, если вы определяете команду в переменную и в дальнейшем вы хотите использовать эту команду, то вы должны использовать функцию eval:
/home/user1 > a="ls | more"
/home/user1 > $a
bash: command not found: ls | more
/home/user1 > # Above command didn't work as ls tried to list file with name pipe (|) and more. But these files are not there
/home/user1 > eval $a
file.txt
mailids
remote_cmd.sh
sample.txt
tmp
/home/user1 >
функции "eval" является характерной чертой большинства интерпретируемых языках (ИКЛ
, питон
, Рубин
...), а не только снаряды. Это's используемый для динамического выполнения кода.
В раковинах, это'ы реализован как встроенная команда оболочки.
В основном, функции "eval" принимает строку в качестве аргумента и вычисляет/переводит код в нем. В оболочках, функции "eval" может принимать более одного аргумента, а функции "eval" просто объединяет тех, чтобы сформировать строку, чтобы оценить.
Это's очень мощный, потому что вы можете динамически создавать код и запустить его, то вы можете'т сделать на компилируемых языках, как C.
Как:
varname=$1 varvalue=$2
eval "$varname=\$varvalue" # evaluate a string like "foo=$varvalue"
# which in Bourne-like shell language
# is a variable assignment.
Но это's также опасно, как это's важно, чтобы санировать динамический (внешней) части, что передается функции "eval" по той причине, это'ы интерпретируется как шелл-кода.
Например, выше, если 1 $
- это зло-команда; ВАР
, ивал
закончится-до оценки зло-команда; ВАР код=$varvalue раковину, а затем запустить, что зло-команда
.
По злобе ивал
часто преувеличен.
ОК, Это'опасно, но по крайней мере мы знаем, что это'ы опасно.
Много других команд будет оценивать шелл-кода в свои аргументы, если не продезинфицировать, как (в зависимости от оболочки), [
ака тест
, экспорт
, е
, ГНУ СЭД
, неужели
и конечно ш
/Баш
/Перл
, а все переводчики...
Примеры (здесь с помощью команды unameкак
зло-командаи
$` в качестве внешних непроверенные данные):
$ a='$(uname>&2)' sh -c 'eval "echo $a"'
Linux
$ a='x[0$(uname>&2)]' mksh -c 'export "$a=$b"'
Linux
$ a='x[0$(uname>&2)]' ksh93 -c 'printf "%d\n" "$a"'
Linux
0
$ a='x[0$(uname>&2)]' ksh93 -c '[ "$a" -gt 0 ]'
Linux
$ a=$'bar/g;e uname>&2\n;s//'; echo foo | sed "s/foo/$a/g"
Linux
bar
$ a='";system("uname");"'; awk "BEGIN{print \"$a\"}"
Linux
$ a=';uname'; sh -c "echo $a"
Linux
Те, седьмого
, экспорт
... команды можно считать более опасным, потому что, пока он's очевидным ивала " в переменной$var" и приведет содержимое переменной$VAR
, чтобы быть оценены как shell-код, это's не так очевидно с СЭД "и с именем/foo/$VAR в/то" " или " экспорт " и$переменная=значение" и
или не ВАР и quot$; - ГТ 0 ]
. В dangerosity то же, но это'ы скрыты в этих других командах.
в
eval-это командная оболочка, которая обычно реализуются как встроенные. В POSIX указано как часть [на "2.14. Специальные встроенные утилиты на"][Особый] на входе [на"ивала" и][ивал]. Что встроенные средства:
сроком на "встроенный" и предполагает, что Shell может выполнять утилита напрямую и не нужно искать его.
Что она делает?
В простых терминах: осуществляет ввод строка, которая будет проанализирована дважды.
Как это сделать?
Оболочка имеет последовательность шагов, которые следует, чтобы "Процесс" а линии. Вы могли бы [посмотрите на это изображение][clisteps] и понимаю, что eval-это единственная линия, которая идет вверх, вернитесь к шагу 1, на левом. Из [описание стандарта POSIX][shellintro]:
2.1 оболочки введение
- Оболочка считывает входные данные ....
- Снаряд разбивает входной сигнал на лексемы-слова и операторы
- Оболочка анализирует вклад в простое и команды соединения.
- Оболочка выполняет различные расширения (отдельно) ...
- Оболочка выполняет перенаправление и удаляет операторы перенаправления и их операнды из списка параметров.
- Оболочка выполняет функции, встроенные шкафы, исполняемый файл или скрипт ...
- Оболочка дополнительно ждет завершения выполнения команды и получает статус выхода. На шаге 6 встроенный будет выполнен. На шаге 6 ивала причины обрабатываемой строке, чтобы быть отправлены обратно к шагу 1. Это единственное условие, при котором последовательность выполнения возвращается. вот почему я говорю: с эвал в строке ввода разбирается дважды.
Эффекты# дважды разбора.
Первый.
И самый важный эффект для понимания. Заключается в том, что одним из последствий первой линии подчиняется семь шагов оболочки показано выше, цитирую. Внутри Шаг 4 (разложения), есть также [последовательность шагов для выполнения всех разложений][расширения], последний из которых *цитата переезд*: удаление цитата всегда должна выполняться последней. Поэтому, всегда, есть один уровень цитирование удалены.
Второй.
Как следствие, что первое следствие, дополнительные/различные части линии становятся открытыми для разбора консоли и все остальные шаги.
Пример.
Косвенности.
Что позволяет выполнять косвенные дополнения:
a=b b=c ; eval echo \$$a ### shall produce "c"
Почему?
Потому что на первый цикл, первый$
, - цитирует.
Как таковая, она игнорируется для расширения оболочкой.
Следующий $
с названием расширяется, чтобы произвести запах мяты&; б&;.
Затем, в один уровень цитирование удалено, делая первый $
без кавычек.
Конец первого цикла.
Это потом, на втором петля, что строка $B
это прочитать оболочкой.
Тогда расширена, чтобы "с" и
И приводят в качестве аргумента к "Эхо".
Чтобы "посмотреть" что оценку будет производить на первом круге (на повторной оценке), использовать Эхо. Или любую команду/скрипт/программу, которая четко показывает аргументы:
$ a=b b=c
$ eval echo \$$a;
c
Заменить ивала Эхо, чтобы "посмотреть" Что происходит:
$ echo echo \$$a
echo $b
Можно также показать всех "части" по линии с:
$ printf '<%s> ' echo \$$a
<echo> <$b>
Которая, в данном примере, только одно эхо, и одна переменная, но вспомнить его, чтобы помочь в оценке более сложных случаях.
Надо сказать, что: произошла ошибка в приведенном выше коде, вы можете увидеть его?. Прост: есть некоторые недостающие цитаты. Как? вы можете спросить. Простой, пусть's поменять переменные (не код):
$ a=b b="hi jk"
$ eval echo \$$a
hi jk
Увидеть недостающие пробелы?
Это происходит потому, что значение внутри $B
был разделен оболочки.
Если это не убедит вас, попробуйте это:
$ a=b b="hi * jk"
$ eval echo \$$a ### warning this will expand to the list
### of all files in the present directory.
Недостающие цитаты. Чтобы сделать его правильно работать (добавлять внутренние в "$" Мои и внешних
\"` в кавычки).
Попробуйте этот (совершенно безопасно):
$ a=b b="hi * jk"
$ eval echo \" \$"$a" \"
hi * jk
нет страницы человека за это.. Нет, нет независимого Man-странице для этого. Поиск руководство с мужчиной -Ф ивала "или даже" шоу по поводу оценки-нет записи. Он входит внутрь человека Баш
. Как и любая встроенная. Поиск на "команды оболочки строение" а затем и"ивала" по. Более простой способ получить помощь-это: В bash, вы могли бы сделать
помощь ивал`, чтобы просмотреть справку для встроенной.Почему ивала называемое зло?
Потому что это обязательный текст для динамического кода. Другими словами, он преобразует список ее аргументов (и/или расширения такие аргументы) в исполняемую строку. Если по какой-либо причине, аргумент был установлен злоумышленник, вы будет выполнения кода злоумышленника. Или даже проще, с эвал вы говорите, кто определил стоимость одного или нескольких аргументов: С'МОН, сидеть здесь и введите любой командной строки, я буду выполнять ее со своими способностями. Это опасно? Должно быть понятно всем, что это. Правила безопасности для оценки, должны быть: Только выполнять функцию eval на переменные, в которые вы дали это's стоимостью. Читать подробно здесь.
Этот пример может пролить свет:
#!/bin/bash
VAR1=25
VAR2='$VAR1'
VAR3='$VAR2'
echo "$VAR3"
eval echo "$VAR3"
eval eval echo "$VAR3"
Выход выше скрипт:
$VAR2
$VAR1
25