Можно использовать радугу, который colorizes строки на основе регулярных выражений:
rainbow --red='SEVERE.*' --green='INFO.*' tail -f my-file.log
Это также прибывает связанное предопределенными конфигурациями, например, для журналов Tomcat:
rainbow --config=tomcat tail -f my-file.log
(правовая оговорка: Я - автор),
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
$foo
со значением '10'
и $x
со значением 'foo'
. $y
, который состоит из строки '$foo'
. Со знаком доллара нужно оставить '$'
. echo $y
.'$foo'
eval
. Это сначала оценит $x
к строке 'foo'
. Теперь у нас есть оператор y=$foo
который будет оценен к y=10
.echo $y
теперь значение '10'
.Это - общая функция на многих языках, например, Perl и JavaScript. Взгляните на perldoc оценку для большего количества примеров: http://perldoc.perl.org/functions/eval.html
Да, 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
:
andcoz@...:~> $( echo VAR=value )
bash: VAR=value: command not found
andcoz@...:~> echo $VAR
<empty line>
Оболочка пытается выполниться echo
и VAR=value
как две отдельных команды. Это бросает ошибку о второй строке. Присвоение остается неэффективным.
andcoz@...:~> eval $( echo VAR=value )
andcoz@...:~> echo $VAR
value
Слияния оболочки (связывают) две строки echo
и VAR=value
, синтаксические анализы этот единый блок согласно соответствующим правилам и выполняют его.Наконец, что не менее важно, eval
может быть очень опасная команда. Любой вход к eval
команда должна быть тщательно проверена для предотвращения проблем безопасности.
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
мощная команда и если Вы намереваетесь использовать ее, необходимо очень стараться препятствовать возможным угрозам безопасности, которые идут с нею.
Оператор 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 - это команда оболочки, которая обычно реализуется как встроенная.
В POSIX он указан как часть «2.14. Специальные встроенные утилиты» в записи «eval» .
Что означает "встроенный":
Термин "встроенный" подразумевает, что оболочка может выполнять утилиту напрямую и не нуждается в ее поиске.
Проще говоря: заставляет строку ввода дважды анализироваться .
У оболочки есть последовательность шагов, которые она выполняет для «обработки» строки. Вы могли взглянуть на это изображение и понять, что eval - единственная строка, которая идет вверх, назад к шагу 1, слева. Из описания POSIX :
2.1 Введение в оболочку
- Оболочка считывает свой ввод ....
- Оболочка разбивает ввод на токены: слова и операторы
- Оболочка анализирует ввод на простые и составные команды.
- Оболочка выполняет различные расширения (по отдельности) ...
- Оболочка выполняет перенаправление и удаляет операторы перенаправления и их операнды из списка параметров.
- Оболочка выполняет функцию, встроенный исполняемый файл или сценарий ...
- Оболочка дополнительно ожидает завершения команды и собирает статус выхода.
На шаге 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
- это особенность большинство интерпретируемых языков ( 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]
. Опасность такая же, но таится в других командах.
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
Мой опыт работы с 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}
Это может быть полезно, чтобы воспользоваться возвратом другой команды перед обработкой основной команды (, например, получить свойства файла или состояние удаленного сервера)
Немного запоздал с этим, но этот небольшой пример из моего вывода на консоль показывает поведение eval по сравнению с запуском скрипта. Он показывает, что eval оценивает строку (, будь то из файла или переменной ), и запускает команду в текущей оболочке, в которой она находится, по сравнению с запуском скрипта, который запускается в своей собственной оболочке и выходит обратно в текущую оболочку.. (, но и для запуска сценария в текущей среде оболочки вы можете просто поставить точку и пробел перед именем файла сценария оболочки)
$ pwd
/home/user1
$ cat myscript.sh
cd Desktop
$./myscript.sh
$ pwd
/home/user1
$ eval $(cat myscript.sh)
$ pwd
/home/user1/Desktop
eval
встроенное, не функция. На практике, созданный-ins ведут себя много как функции, которые не имеют определения в языке, но не совсем (как становится очевидным, если Вы скручиваетесь достаточно для определения вызванной функцииeval
). – Gilles 'SO- stop being evil' 23.10.2011, 04:17