La differenza più importante tra
bash -c "$1"
E
eval "$1"
È che il primo viene eseguito in una subshell e il secondo no. Così:
set -- 'var=something'
bash -c "$1"
echo "$var"
PRODUZIONE:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
PRODUZIONE:
something
Non ho idea del perché qualcuno avrebbe mai usato l'eseguibile bash
in quel modo, però. Se è necessario invocarlo, utilizzare il POSIX integrato garantito sh
. O (subshell eval)
se desideri proteggere il tuo ambiente.
Personalmente, preferisco soprattutto le shell .dot
.
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
PRODUZIONE
something1
something2
something3
something4
something5
MA LO AVETE BISOGNO DI TUTTO?
L'unica causa da utilizzare, in realtà, è nel caso in cui la variabile ne assegni o valuti un'altra, oppure la suddivisione delle parole è importante per l'output.
Per esempio:
var='echo this is var' ; $var
PRODUZIONE:
this is var
Funziona, ma solo perché echo
non importa del suo conteggio degli argomenti.
var='echo "this is var"' ; $var
PRODUZIONE:
"this is var"
Vedere? Le virgolette vengono fornite perché il risultato dell'espansione della shell $var
non viene valutato quote-removal
.
var='printf %s\\n "this is var"' ; $var
PRODUZIONE:
"this
is
var"
Ma con eval
o sh
:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
PRODUZIONE:
this is var
this is var
Quando usiamo eval
o sh
la shell fa un secondo passaggio ai risultati delle espansioni e li valuta anche come un potenziale comando, e quindi le virgolette fanno la differenza. Puoi anche fare:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
PRODUZIONE
this is var
e='echo foo'; $e
funziona benissimo.