Разбиение на слова происходит довольно поздно при оценке команды. Что наиболее важно для вас, это происходит после раскрытия переменных и подстановки команд.
Это означает, что вторая строка в
s="echo a; echo b"
echo $($s)
сначала расширит $s
до echo a; echo b
, а затем эта команда будет выполнена без разделения на составную команду, состоящую из двух echo
s.
(details:$s
разбивается на четыре слова: echo
, a;
, echo
и b
. Инкапсулирующий $(...)
выполняет это как одну команду, echo
с тремя аргументами, a;
, echo
и b
.)
То, что дается самому внешнему echo
, является строкойa; echo b
(на самом деле из трех слов, поскольку $(...)
не заключено в кавычки ), так как это было то, что было выведено самым внутренним echo
.
Сравните это с
s1="echo a"
s2="echo b"
echo $($s1;$s2)
что приводит к ожидаемому результату.
Да, "eval
зло", большую часть времени,и sh -c
неуклюжий и такой же хрупкий. Но если у вас есть фрагмент кода оболочки, которому вы доверяете в строке в сценарии оболочки, то эти инструменты являются единственными (? )способ заставить этот код выполняться должным образом, так как это часто требует явной оценки текста в строке как кода оболочки (со всеми фазами оценки от начала до конца ). Особенно, если это составная команда.
Я думаю, что только из-за тесной связи оболочки Unix с текстом вам посчастливилось echo $($s)
выполнить что-то вообще .
Просто подумайте о шагах, которые вам нужно предпринять, чтобы заставить программу на C выполнять фрагмент кода на C, который ей передается в виде строки...