Самое важное различие между
bash -c "$1"
А также
eval "$1"
Это первый работает в подоболочке, а второй нет. Так:
set -- 'var=something'
bash -c "$1"
echo "$var"
ВЫХОД:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
ВЫХОД:
something
Я понятия не имею, почему кто-то когда-либо использовал исполняемый файл bash
таким образом. Если вы должны вызвать его, используйте гарантированно встроенный POSIX sh
. Или (subshell eval)
если вы хотите защитить свою среду.
Лично я предпочитаю оболочку .dot
превыше всего.
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
ВЫХОД
something1
something2
something3
something4
something5
НО ЭТО ВАМ НУЖНО?
Единственная причина, по которой можно использовать либо, действительно, в том случае, если ваша переменная фактически назначает или оценивает другую, или разделение слов важно для вывода.
Например:
var='echo this is var' ; $var
ВЫХОД:
this is var
Это работает, но только потому, echo
что не заботится о количестве аргументов.
var='echo "this is var"' ; $var
ВЫХОД:
"this is var"
Видеть? Двойные кавычки приходят, потому что результат расширения оболочки $var
не оценивается для quote-removal
.
var='printf %s\\n "this is var"' ; $var
ВЫХОД:
"this
is
var"
Но с eval
или sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
ВЫХОД:
this is var
this is var
Когда мы используем eval
или, sh
оболочка берет второй проход в результатах расширений и оценивает их как потенциальную команду, и поэтому кавычки имеют значение. Вы также можете сделать:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
ВЫХОД
this is var
e='echo foo'; $e
работает просто отлично.