Оболочки Unix выполняют серию преобразований в каждой строке ввода перед их выполнением. Для большинства оболочек это выглядит примерно так (взято из справочной страницы bash
):
- начальное разбиение слова
- расширение скобки
- расширение тильды
- параметр, переменное и арифметическое расширение
- подстановка команд
- вторичное разделение слов
- расширение пути (или глобализация)
- удаление цитаты
Использование $cmd
напрямую заменяет его вашей командой во время фазы расширения параметра, а затем он подвергается всем следующим преобразованиям.
Использование eval "$cmd"
ничего не делает до фазы удаления кавычек, где $cmd
возвращается как есть и передается в качестве параметра eval
, функция которого - снова выполнить всю цепочку перед выполнением.
Таким образом, в основном они одинаковы в большинстве случаев и отличаются, когда ваша команда использует шаги преобразования вплоть до раскрытия параметров. Например, используя расширение скобки:
$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz