LINUX.ORG.RU

Объясните толком

 ,


1

3

для чего в shell'е нужна команда eval? Я честно читал ABS Guide, я гуглил, я пытался вникнуть. Голова не соображает, не могу понять. Хелп ми, плиз.

★★★★★

Ответ на: комментарий от Spirit_of_Stallman
setvar_rot_13()              # Криптование по алгоритму "rot13"
{
  local varname=$1 varvalue=$2
  eval $varname='$(echo "$varvalue" | tr a-z n-za-m)'
}

setvar_rot_13 var "foobar"   # Пропустить слово "foobar" через rot13.
echo $var                    # sbbone

echo $var | tr a-z n-za-m    # foobar
                             # Расшифровывание.
exit 0
#!/bin/bash

y=`eval ls -l`  # Подобно y=`ls -l`
echo $y         # но символы перевода строки не выводятся, поскольку имя переменной не в кавычках.
echo
echo "$y"       # Если имя переменной записать в кавычках -- символы перевода строки сохраняются.

echo; echo

y=`eval df`     # Аналогично y=`df`
echo $y         # но без символов перевода строки.

#  Когда производится подавление вывода символов LF (перевод строки), то анализ
#+ результатов различными утилитами, такими как awk, можно сделать проще.

exit 0
IPR ★★★★★
() автор топика
Ответ на: комментарий от IPR

clik
Вот тут удачно объяснили.
В англицком разбираешься, или отзеркалить пример?
ЗЫ: я вспомнил где я пользовал этот эвал, аж стыдно стало что забыл про это.

Spirit_of_Stallman ★★★
()
Последнее исправление: Spirit_of_Stallman (всего исправлений: 2)

Эта команда возвращает зхначение значения переменной. Например:

a=5
b=a
c='$'$b
echo $c

выведет $a, но

a=5
b=a
eval c='$'$b
echo $c

выведет 5

Kindly_Cat
()
Ответ на: комментарий от Kindly_Cat

И всё? В ABSG травили что-то ещё.

IPR ★★★★★
() автор топика
Ответ на: комментарий от IPR

Ну, Kindly_Cat, это уже по сути сделал, но немного сумбурно.
Проведу пошагово:

# объявим x
x=sometext

# дальше мы объявляем "z"
z='$'$x

# присваиваем к ней знак "$" и переменную "$x"
# т.е. интерпретатор это будет видеть как "z='$sometext'"
# проверяем на деле и видим именно это
echo $z
выхлоп> $sometext

# теперь если сделать это же присвоение через eval
eval z='$'$x

# то всё что будет дальше интерпретатор увидит уже с знанием того, что необходимо "выполнить" всё что за эвалом
# и на деле он сначала преобразует до "z='$sometext'", а потом обнаружив "$sometext" попытается и её преобразовать как переменную
# но поскольку у нас нет объявленного "sometext" - z будет пуста; проверим:
echo $z
выхлоп> 

# теперь объявим "sometext" и повторим присвоение к z
sometext='foobar';
eval z='$'$x;
echo $z
выхлоп> foobar

Spirit_of_Stallman ★★★
()
Последнее исправление: Spirit_of_Stallman (всего исправлений: 3)
Ответ на: комментарий от Spirit_of_Stallman

А вот если «где это можно использовать на деле» - это хороший метод что бы объединять скрипты, так сказать.
Есть у тебя скрипт test_1.sh

#!/bin/bash
funcion testfunc(){
    echo "sometext"
}
и test_2.sh, в котором ты бы хотел пользовать эту функцию, из test_1; Решить это можно было бы эвалом.
#!/bin/bash
eval "$(cat ./test_1.sh)"
# и теперь в test_2 ты можешь вызывать testfunc (по сути эвал переинтерпритировал весь test_1 для test_2
testfunc;
выхлоп> sometext

Spirit_of_Stallman ★★★
()
Последнее исправление: Spirit_of_Stallman (всего исправлений: 1)
Ответ на: комментарий от Spirit_of_Stallman

А вот если «где это можно использовать на деле» - это хороший метод что бы объединять скрипты, так сказать.

чем это лучше, чем "." ?

maloi ★★★★★
()
Ответ на: комментарий от Spirit_of_Stallman

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

Он имеет ввиду: чем это eval «$(cat ./test_1.sh)» лучше обычной source ./test_1.sh или . ./test_1.sh

IPR ★★★★★
() автор топика

cmd=«do smtng»
$cmd

Error: unknown command 'do smtng'

eval $cmd

'do' 'smtng' - ok dude. you d'boss

yozan
()
Ответ на: комментарий от IPR

Не лучше, оно просто для разных вещей. Я eval, к примеру, юзал для указания в общем конфиге команды для запуска после применения настроек веб-интерфейса, а source для загрузки этого конфига

В конфиге было как-то так:

#config

postrun='/etc/init.d/service reload'
postrun_hard='/etc/init.d/service restart'

А в скрипте-обработчике как-то так:

source $service/config.sh

...

if [ "$act" == 'apply' ]; then
  eval $postrun
elif [ "$act" == 'restart' ]; then
  eval $postrun_hard
fi
derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 2)
Ответ на: комментарий от Spirit_of_Stallman

Но стоит заметить что это палка о двух концах.
eval переинтерпретирует, но не позволит передвать функциям данные, если мне не изменяет память, а вот source - это делать позволяет.

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от derlafff

Ладно, а чем eval $VAR лучше тупо ${VAR} ?

Я, если есть необходимость подставить содержимое переменной в качестве команды, делаю тупо подстановку. Брат жив, об evel даже не знал.

IPR ★★★★★
() автор топика
Ответ на: комментарий от IPR

Ладно, а чем eval $VAR лучше тупо ${VAR} ?

Далеко не везде брат останется живым.
С ssh'ем твой вариант не прокатит, в скрипте.

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от IPR

Как правильно заметил сэр derlafff - всему есть своё назначение.
Если важен оригинальный $BASH_SOURCE, и нет необходимости передавать вливаемому куску внутренние данные - эвал тут самое оно.
В остальных случаях - остальные варианты.

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от Spirit_of_Stallman

ну, я немного соврал. у меня zsh :)

вообще получается тот же eval, только так он как-то красивее и яснее оформлен

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от Spirit_of_Stallman

не, соврал :) специально заменил % на $ и zsh на bash, думая, что поведение в них одинаковое

derlafff ★★★★★
()

Ладно, всем спасибо, буду заниматься любовью с getopts.

IPR ★★★★★
() автор топика

Код:

#!/bin/sh

cmd='echo ${var}'
var=6

printf "cmd \`\`${cmd}'' prints "
eval ${cmd}

Результат:

$ ./test.sh
cmd ``echo ${var}'' prints 6

Вопросы?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.