Как работает shell eval?

#shell #eval

#оболочка #оценка

Вопрос:

Итак, я написал скрипт, который принимает аргумент. Аргумент указывает, какие тесты запускать, будь то qa или dev. У меня есть скрипт, который изменяет значение в файле свойств на основе аргумента, изначально:

 dev="site1.com"
qa="site2.com"

if [ $1 == "dev" ]; 
then
   sed -i "s/site=.*/site=${dev}/g" myfile.properties
else ...
 

Но я изменил его на:

 dev="site1.com"
qa="site2.com"

eval environment=$1
sed -i "s/site=.*/site=${environment}/g" myfile.properties
 

теперь мне не нужна структура if-else, основанная на аргументе.

Как это работает, что «eval environment = $ $ 1» делает так, что «$ {environment}» на самом деле будет «$ {dev}», если аргументом было «dev»?

Другими словами, используя dev в качестве аргумента (sh script.sh dev)
${environment} == $ {dev} вместо $ {environment} == «dev»?

Комментарии:

1. Что именно вы спрашиваете?

2. Ваше изменение не устраняет необходимость в условном. Теперь вы переписываете файл, даже когда в этом нет необходимости.

3. Скрипт всегда переписывал файл, даже когда в этом не было необходимости. Я просто удостоверяюсь, что свойство site всегда будет корректным при запуске скрипта, не обращая внимания на все прошлые запуски.

4. Нет, вы изменили логику. Раньше перезапись выполнялась только в том случае, если $1 содержала «dev»; теперь это происходит, если оно содержит что-то еще (включая недопустимую метку).

5. Мой плохой, я не включил весь код. Я только хотел знать, как работает оценка. Полный сценарий включает начальный блок if для печати сообщения об ошибке, если пользователь не использует аргументы ‘dev’ или ‘qa’, таким образом, если бы они использовали один из этих аргументов, файл был бы перезаписан с соответствующим сайтом.

Ответ №1:

Как это eval работает?

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

Учитывая:

 eval environment=$1
 

Первый проход создает:

 eval environment=$dev
 

eval Затем интерпретирует это как

 environment=site1.com
 

Проблема в коде изначально в вопросе

Вы не ставите пробелы вокруг назначений в shell, даже в eval .

 dev="site1.com"
qa="site2.com"

eval environment=$1
sed -i "s/site=.*/site=${environment}/g" myfile.properties
 

В Bash вы бы использовали:

 environment=${!1}
 

Это позволяет избежать явного eval , что может быть опасно, если пользователь (ab) набрал sh yourscript '$(rm -fr $HOME amp;)' вместо sh yourscript dev . Если вы используете eval , вам лучше тщательно проверить, что вы получаете для оценки.

Комментарии:

1. Я исправил это, моя ошибка. Однако дело не в этом. Исправив пробелы, я просто пытаюсь выяснить, почему $ {environment} == $ {dev}, а не $ {environment} == «dev». Я думаю, может быть, как eval работает в первую очередь.

2. @elrobe: смотрите Обновление. Обратите внимание, что предостережения об использовании eval остаются в силе.

3. Потрясающе! Спасибо! Это объяснение имеет большой смысл.