Найважливіша різниця між
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
працює просто чудово.