Najważniejsza różnica między
bash -c "$1"
I
eval "$1"
Czy to pierwsze działa w podpowłoce, a drugie nie. Więc:
set -- 'var=something'
bash -c "$1"
echo "$var"
WYDAJNOŚĆ:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
WYDAJNOŚĆ:
something
Nie mam jednak pojęcia, dlaczego ktokolwiek miałby używać tego pliku wykonywalnego bash
w ten sposób. Jeśli musisz go wywołać, użyj wbudowanej gwarancji POSIX sh
. Lub (subshell eval)
jeśli chcesz chronić swoje środowisko.
Osobiście wolę .dot
przede wszystkim muszle .
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
WYNIK
something1
something2
something3
something4
something5
ALE POTRZEBUJESZ W ogóle?
Jedynym powodem użycia jednego z nich jest to, że twoja zmienna faktycznie przypisuje lub ocenia inną, lub dzielenie słów jest ważne dla wyniku.
Na przykład:
var='echo this is var' ; $var
WYDAJNOŚĆ:
this is var
To działa, ale tylko dlatego, echo
że nie obchodzi go liczba argumentów.
var='echo "this is var"' ; $var
WYDAJNOŚĆ:
"this is var"
Widzieć? Pojawiają się podwójne cudzysłowy, ponieważ wynik rozszerzenia powłoki $var
nie jest oceniany quote-removal
.
var='printf %s\\n "this is var"' ; $var
WYDAJNOŚĆ:
"this
is
var"
Ale z eval
lub sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
WYDAJNOŚĆ:
this is var
this is var
Kiedy używamy eval
lub sh
powłoka bierze drugie przejście na wyniki rozszerzeń i ocenia je również jako potencjalne polecenie, więc cudzysłowy mają znaczenie. Możesz także:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
WYNIK
this is var
e='echo foo'; $e
działa dobrze.