Как выполнить команду, хранящуюся в переменной?
Как правильно вызвать некоторую команду, хранящуюся в переменной?
Есть ли различия между 1 и 2?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
3 ответа:
оболочки Unix выполняют ряд преобразований на каждой строке ввода перед их выполнением. Для большинства оболочек это выглядит примерно так (взято из
bash
manpage):
- начальное разбиение
- фигурные скобки
- расширения
- параметр, переменная и арифметическое расширение
- команду
- вторичное разделение слов
- расширение пути (ака подстановка)
- удаления цитата
используя
$cmd
непосредственно получает его заменяется вашей командой во время фазы расширения параметра, а затем он подвергается всем следующим преобразованиям.используя
eval "$cmd"
ничего не делает до фазы удаления цитаты, где$cmd
возвращается как есть, и передается в качестве параметра вeval
, чья функция состоит в том, чтобы запустить всю цепочку снова перед выполнением.так что в основном они одинаковы в большинстве случаев и отличаются, когда ваша команда использует шаги преобразования до расширения параметра. Например, с помощью расширения скобки:
$ cmd="echo foo{bar,baz}" $ $cmd foo{bar,baz} $ eval "$cmd" foobar foobaz
Если вы просто сделать
eval $cmd
когда мы это сделаемcmd="ls -l"
(интерактивно и в скрипте) получаем желаемый результат. В вашем случае у вас есть труба с grep без шаблона, поэтому часть grep завершится с сообщением об ошибке. Просто$cmd
генерирует сообщение" команда не найдена " (или что-то подобное). Поэтому попробуйте использовать eval и использовать готовую команду, а не ту, которая генерирует сообщение об ошибке.