Какова команда “оценки” в ударе?

Можно использовать радугу, который colorizes строки на основе регулярных выражений:

rainbow --red='SEVERE.*' --green='INFO.*' tail -f my-file.log

Это также прибывает связанное предопределенными конфигурациями, например, для журналов Tomcat:

rainbow --config=tomcat tail -f my-file.log

(правовая оговорка: Я - автор),

197
23.04.2016, 01:32
9 ответов

eval часть POSIX. Интерфейс, который может быть встроенной оболочкой.

Его описанный в "Руководстве Программиста POSIX": http://www.unix.com/man-page/posix/1posix/eval/

eval - construct command by concatenating arguments

Это возьмет аргумент и создаст команду из него, которая будет выполняться оболочкой. Это - пример страницы справочника:

1) foo=10 x=foo
2) y='$'$x
3) echo $y
4) $foo
5) eval y='$'$x
6) echo $y
7) 10
  1. В первой строке Вы определяете $foo со значением '10' и $x со значением 'foo'.
  2. Теперь определите $y, который состоит из строки '$foo'. Со знаком доллара нужно оставить '$'.
  3. Проверять результат, echo $y.
  4. Результатом будет строка '$foo'
  5. Теперь мы повторяем присвоение с eval. Это сначала оценит $x к строке 'foo'. Теперь у нас есть оператор y=$foo который будет оценен к y=10.
  6. Результат echo $y теперь значение '10'.

Это - общая функция на многих языках, например, Perl и JavaScript. Взгляните на perldoc оценку для большего количества примеров: http://perldoc.perl.org/functions/eval.html

147
27.01.2020, 19:27
  • 1
    В терминологии оболочки, eval встроенное, не функция. На практике, созданный-ins ведут себя много как функции, которые не имеют определения в языке, но не совсем (как становится очевидным, если Вы скручиваетесь достаточно для определения вызванной функции eval). –  Gilles 'SO- stop being evil' 23.10.2011, 04:17
  • 2
    спасибо, зафиксировал тот :-) –  echox 25.10.2011, 17:14
  • 3
    Каково различие между оценкой и обратными галочками '? –  JohnyTex 20.03.2015, 11:16
  • 4
    являются сокращением от выполнения другой всей оболочки, означая, что у Вас будет другой дочерний процесс bash/sh, работающий в рамках Вашего сценария. –  Aaron R. 19.10.2015, 18:38
  • 5
    Почему $y эха (этап 3) возвращает нечто (10) вместо $foo? (т.е. просто значение нечто вместо строкового $ + значение нечто)? –  JohnDoea 25.12.2016, 19:00

Да, eval удар внутренняя команда, таким образом, она описана в 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.

Обычно это используется в сочетании с Заменой Команды. Без явного eval, оболочка пытается выполнить результат замены команды, не оценить его.

Скажите, что Вы хотите кодировать эквивалент VAR=value; echo $VAR. Отметьте различие в том, как оболочка обрабатывает записи echo VAR=value:

  1. andcoz@...:~> $( echo VAR=value )
    bash: VAR=value: command not found
    andcoz@...:~> echo $VAR
    <empty line>
    

    Оболочка пытается выполниться echo и VAR=value как две отдельных команды. Это бросает ошибку о второй строке. Присвоение остается неэффективным.

  2. andcoz@...:~> eval $( echo VAR=value )
    andcoz@...:~> echo $VAR
    value
    
    Слияния оболочки (связывают) две строки echo и VAR=value, синтаксические анализы этот единый блок согласно соответствующим правилам и выполняют его.

Наконец, что не менее важно, eval может быть очень опасная команда. Любой вход к eval команда должна быть тщательно проверена для предотвращения проблем безопасности.

65
27.01.2020, 19:27

eval не имеет никакой страницы справочника, потому что это не отдельная внешняя команда, а скорее встроенная оболочка, знача команду, внутреннюю для и известный только оболочкой (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 мощная команда и если Вы намереваетесь использовать ее, необходимо очень стараться препятствовать возможным угрозам безопасности, которые идут с нею.

19
27.01.2020, 19:27

Оператор 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 >
18
27.01.2020, 19:27

Что такое eval?

eval - это команда оболочки, которая обычно реализуется как встроенная.

В POSIX он указан как часть «2.14. Специальные встроенные утилиты» в записи «eval» .
Что означает "встроенный":

Термин "встроенный" подразумевает, что оболочка может выполнять утилиту напрямую и не нуждается в ее поиске.

Что он делает?

Проще говоря: заставляет строку ввода дважды анализироваться .

Как он это делает?

У оболочки есть последовательность шагов, которые она выполняет для «обработки» строки. Вы могли взглянуть на это изображение и понять, что eval - единственная строка, которая идет вверх, назад к шагу 1, слева. Из описания POSIX :

2.1 Введение в оболочку

  1. Оболочка считывает свой ввод ....
  2. Оболочка разбивает ввод на токены: слова и операторы
  3. Оболочка анализирует ввод на простые и составные команды.
  4. Оболочка выполняет различные расширения (по отдельности) ...
  5. Оболочка выполняет перенаправление и удаляет операторы перенаправления и их операнды из списка параметров.
  6. Оболочка выполняет функцию, встроенный исполняемый файл или сценарий ...
  7. Оболочка дополнительно ожидает завершения команды и собирает статус выхода.

На шаге 6 будет выполнена встроенная функция.
На шаге 6 eval вызывает отправку обработанной строки обратно на шаг 1.
Это единственное условие, при котором последовательность выполнения возвращается.

Вот почему я говорю: с eval входная строка анализируется дважды .

Эффекты парсинга дважды.

Первое.

И самый главный эффект, который нужно понять. Это одно из последствий первого раза, когда строка подвергается семи шагам оболочки, показанным выше, - это цитирование . Внутри шага 4 (расширения) есть также последовательность шагов для выполнения всех расширений , последний из которых - Удаление цитаты :

Удаление цитаты всегда должно выполняться последней.

Таким образом, всегда удаляется один уровень цитирования.

Второй.

Как следствие этого первого эффекта, дополнительные / различные части строки подвергаются синтаксическому анализу оболочки и всем остальным этапам.

Пример.

Косвенное обращение.

Это позволяет выполнять косвенные расширения:

a=b b=c    ;    eval echo \$$a            ### shall produce "c"

Почему? Потому что в первом цикле указывается первый $ .
Таким образом, он игнорируется оболочкой для расширений.
Следующий $ с именем a расширяется, чтобы получить "b".
Затем удаляется один уровень цитирования, в результате чего первый $ не цитируется.
Конец первого цикла.

Затем во втором цикле оболочка считывает строку $ b .
Затем расширяется до "c"
И передается в качестве аргумента echo .

Чтобы «увидеть», что eval произведет в первом цикле (для повторной оценки), используйте echo. Или любая команда / сценарий / программа, которая ясно показывает аргументы:

$ a=b b=c
$ eval echo \$$a;
c

Замените eval на echo, чтобы «увидеть», что происходит:

$ echo echo \$$a
echo $b

Также возможно показать все «части» строки с помощью:

$ printf '<%s> ' echo \$$a
<echo> <$b>

В этом примере это только одно эхо и одна переменная, но помните об этом, чтобы помочь в оценке более сложных случаев.

Исправление.

Надо сказать, что: в приведенном выше коде есть ошибка, вы видите ?.
Все просто: отсутствуют некоторые цитаты.

Как? вы можете спросить. Просто, давайте изменим переменные (не код):

$ 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" и внешние \ " кавычки).
Попробуйте это (совершенно безопасно):

$ a=b b="hi      *       jk"
$ eval echo \" \$"$a" \"
hi      *       jk

О руководстве:

Для этого не существует справочной страницы.

Нет, для этого не существует отдельной справочной страницы. Поиск руководства с помощью man -f eval или даже apropos eval не показывают записи.

Он включен в man bash . Как и любой встроенный.
Искать "SHELL ВСТРОЕННЫЕ КОМАНДЫ ", а затем для" eval ".

Более простой способ получить помощь: В bash вы можете выполнить help eval , чтобы увидеть справку по встроенным функциям.

Почему eval называется злом?

Потому что он динамически связывает текст с кодом.

Другими словами: он преобразует список своих аргументов (и / или расширения таких аргументов) в исполняемую строку. по любой причине, аргумент был установлен злоумышленником, вы будете выполнять код злоумышленника.

Или, что еще проще, с eval вы сообщаете тому, кто определил изменил значение одного или нескольких аргументов:

Давай, сядь здесь и набери любую командную строку, я выполню ее со своими полномочиями.

Это опасно? Всем должно быть ясно, что это так.

Правило безопасности для eval должно быть таким:
Выполнять eval только для переменных, которым вы присвоили значение.

Подробнее см. здесь .

18
29.04.2021, 00:58

eval - это особенность большинство интерпретируемых языков ( TCL , python , ruby ​​ ...), а не только оболочки. Он используется для динамической оценки кода.

В оболочках это реализовано как встроенная команда оболочки.

По сути, eval принимает строку в качестве аргумента и оценивает / интерпретирует код в ней. В оболочках eval может принимать более одного аргумента, но eval просто объединяет их, чтобы сформировать строку для оценки.

Это очень мощный инструмент, потому что вы можете динамически создавать код и запускать его, чего нельзя сделать в компилируемых языках, таких как C.

Например:

varname=$1 varvalue=$2
eval "$varname=\$varvalue" # evaluate a string like "foo=$varvalue"
                           # which in Bourne-like shell language
                           # is a variable assignment.

Но это также опасно, поскольку важно очистить динамические (предоставляемые извне) части того, что передается в eval , именно по той причине, что это интерпретируется как код оболочки.

Например, выше, если $ 1 - это злая команда; var , eval закончил бы вычислением злой команды ; var = $ varvalue код оболочки, а затем запустите эту злую команду .

Злоба eval часто преувеличивается.

Хорошо, это опасно, но, по крайней мере, мы знаем, что это опасно.

Многие другие команды будут оценивать код оболочки в своих аргументах, если не дезинфицировать, например (в зависимости от оболочки), [ aka test , export , printf , GNU sed , awk и, конечно, sh / bash / perl и все интерпретаторы ...

Примеры (здесь используется uname в качестве злой команды и $ a в качестве необработанных данных извне):

$ 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

Команды sed , export ... могут считаться более опасными, потому что, хотя очевидно, что eval "$ var" вызовет содержимое $ var для оценки в качестве кода оболочки, это не так очевидно с sed "s / foo / $ var /" или export "$ var = value" или ] ["$ var" -gt 0] . Опасность такая же, но таится в других командах.

14
29.04.2021, 00:58

Este ejemplo puede arrojar algo de luz:

#!/bin/bash
VAR1=25
VAR2='$VAR1'
VAR3='$VAR2'
echo "$VAR3"
eval echo "$VAR3"
eval eval echo "$VAR3"

Salida del script anterior:

$VAR2
$VAR1
25
8
20.08.2021, 13:32

Мой опыт работы с evalон может преобразовывать строковый вывод команды в переменную, этот пример из другой вопрос

eval $(ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width ${FILE})

когда я набираю его прямо в терминал, я получаю

streams_stream_0_width=1280
streams_stream_0_height=720

Этот ответ сохранял каждый ответ в новую переменную для использования внутри скрипта.

IN_WIDTH=${streams_stream_0_width}

Это может быть полезно, чтобы воспользоваться возвратом другой команды перед обработкой основной команды (, например, получить свойства файла или состояние удаленного сервера)

0
20.08.2021, 13:32

Немного запоздал с этим, но этот небольшой пример из моего вывода на консоль показывает поведение eval по сравнению с запуском скрипта. Он показывает, что eval оценивает строку (, будь то из файла или переменной ), и запускает команду в текущей оболочке, в которой она находится, по сравнению с запуском скрипта, который запускается в своей собственной оболочке и выходит обратно в текущую оболочку.. (, но и для запуска сценария в текущей среде оболочки вы можете просто поставить точку и пробел перед именем файла сценария оболочки)

$ pwd
/home/user1

$ cat myscript.sh
cd Desktop

$./myscript.sh

$ pwd
/home/user1

$ eval $(cat myscript.sh)

$ pwd
/home/user1/Desktop
0
20.08.2021, 13:32

Теги

Похожие вопросы