Не помещайте полные команды в переменные."${script}"
- это приглашение к неприятностям.
Наглядный пример:
me ~ > echo -e 'foo bar\nbaz qux' > /tmp/foobar
me ~ > cat /tmp/foobar
foo bar
baz qux
me ~ > sed -e '/foo bar/d' /tmp/foobar
baz qux
me ~ > cmd="sed -e '/foo bar/d' /tmp/foobar"
me ~ > $cmd
sed: -e expression #1, char 1: unknown command: `''
me ~ > ${cmd}
sed: -e expression #1, char 1: unknown command: `''
me ~ > "$cmd"
bash: sed -e '/foo bar/d' /tmp/foobar: No such file or directory
me ~ > "${cmd}"
bash: sed -e '/foo bar/d' /tmp/foobar: No such file or directory
Что здесь происходит?Если вы используете $cmd
без кавычек, sed
имеет следующие 4 аргумента:
-e
'/foo
bar/d'
/tmp/foobar
(да, именно так работают слова в bash).Очевидно, что sed
не может интерпретировать этот бред.
Если вы попытаетесь запустить "$cmd"
или "${cmd}"
, вся строка будет интерпретирована как команда name , пробелы в кавычках и все.Оболочка жалуется, что не может найти исполняемый файл с именем sed -e '/foo bar/d' /tmp/foobar
, и это абсолютно правильно.Также ничего хорошего.
Решение?
Быстрый и грязный взлом
me ~ > eval ${cmd}
baz qux
Работает как положено!Однако eval опасен и не должен использоваться, если вы не являетесь сертифицированным гуру оболочки.(Которые вы, я полагаю, до сих пор нет).Лучшим вариантом является определение функции.
cmd() {
sed -e '/foo bar/d' /tmp/foobar
}
...
cmd