Как выполнить команду, хранящуюся в переменной?
Как правильно вызвать некоторую команду, хранящуюся в переменной?
Есть ли различия между 1 и 2?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
3 ответа:
оболочки Unix выполняют ряд преобразований на каждой строке ввода перед их выполнением. Для большинства оболочек это выглядит примерно так (взято из
bashmanpage):
- начальное разбиение
- фигурные скобки
- расширения
- параметр, переменная и арифметическое расширение
- команду
- вторичное разделение слов
- расширение пути (ака подстановка)
- удаления цитата
используя
$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 и использовать готовую команду, а не ту, которая генерирует сообщение об ошибке.