Каков правильный способ вызова некоторой команды, хранящейся в переменной? 
Есть ли различия между 1 и 2?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
Каков правильный способ вызова некоторой команды, хранящейся в переменной? 
Есть ли различия между 1 и 2?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
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" (в интерактивном режиме и в script), получаем желаемый результат. В вашем случае у вас есть труба с grep без шаблона, поэтому команда grep завершится с сообщением об ошибке. Просто $cmd будет генерировать сообщение "команда не найдена" (или некоторое такое).
Поэтому попробуйте использовать eval и используйте готовые команды, а не те, которые генерируют сообщение об ошибке.
 $cmd просто заменит переменную на значение, которое будет выполнено в командной строке. eval "$cmd" выполняет расширение переменной и подстановку команд перед выполнением результирующего значения в командной строке
 2-й метод полезен, когда вы хотите выполнить команды, которые не являются гибкими, например. for я in {$a..$b} 
 Цикл форматирования не будет работать, потому что он не допускает переменных. 
 В этом случае обходной путь - bash или eval.
Протестировано на Mac OSX 10.6.8, Bash 3.2.48
Я думаю, вы должны поставить
'
 (backtick) символы вокруг вашей переменной.