Является ли eval $ (имя файла cat) тем же, что и имя исходного файла?

9

Работая над некоторыми функциями bash, я не знал source ...команды, поэтому я использовал eval $(cat ...)вместо этого. Теперь мне интересно, должен ли я менять каждое использование этого, или это просто та же самая функция?

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

Вениамин
источник

Ответы:

6

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

Попробуйте, например, следующий файл с обоими методами:

for i in 1 2 3; do
 echo $i
done

cat<<EOF
a
b
c
EOF
Флориан Диш
источник
4
Если вы используете кавычки, пробелы останутся нетронутыми:eval "$(cat file)"
Гленн Джекман
1
Да, это тоже должно сработать. Но если нужно все равно изменить код, я предпочитаю, так sourceкак это команда, созданная специально для этого.
Флориан Диш,
9

Как уже упоминалось @glennjackman, вы захотите заключить в кавычки подстановку команд, иначе разделение слов и расширение имени пути изменят содержимое, прежде чем оно будет удалено. И хотя обе команды будут выполнять команды из файла, существуют различия.

  • При создании сценария будут изменены различные специальные переменные оболочки, в основном BASH_SOURCE, BASH_LINENOи FUNCNAMEмассивы. Они полезны для печати сообщений об ошибках и отладки.

  • Вы можете вернуться из исходного скрипта с помощью returnкоманды ( help return). С eval вы не получите такой эффект. И точно так же ловушка ВОЗВРАТА не сработает для eval.

  • При поиске сценария вы можете передать ему аргументы. Вы не можете сделать это с этим Eval.

  • При использовании eval команда подстановки считывает все содержимое файла в память, а затем передает его в eval. Когда вы его загрузите, bash будет читать из файла по ходу дела.

geirha
источник
1

Хорошее резюме того, что source, eval и exec делают здесь: http://www.unix.com/shell-programming-scripting/54347-bash-shell-exec-eval-source-looking-help-understand.html

Я думаю, что использование eval и source'ing для файла сделает то же самое. Я не совсем уверен, однако, что переменные внутри индекса будут вести себя одинаково в любом случае. Я бы порекомендовал использовать исходники, если это возможно, потому что это более простой способ сделать ваш код более читабельным.

Hinz
источник
3
полностью тангенциальный: у bash есть сокращение для $(cat file)->$(< file)
glenn jackman