Как выполнить команду, хранящуюся в переменной?


Как правильно вызвать некоторую команду, хранящуюся в переменной?
Есть ли различия между 1 и 2?

#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
3 57

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 и использовать готовую команду, а не ту, которая генерирует сообщение об ошибке.

Я думаю, что Ю поставил ' символы вокруг вашей переменной (тот, с ~ если сдвиг нажата)