Sự khác biệt quan trọng nhất giữa
bash -c "$1"
Và
eval "$1"
Có phải cái trước chạy trong một subshell và cái sau thì không. Vì thế:
set -- 'var=something'
bash -c "$1"
echo "$var"
ĐẦU RA:
#there doesn't seem to be anything here
set -- 'var=something'
eval "$1"
echo "$var"
ĐẦU RA:
something
Tôi không biết tại sao mọi người sẽ sử dụng thực thi bashtheo cách đó, mặc dù. Nếu bạn phải gọi nó, hãy sử dụng POSIX được tích hợp sẵn sh. Hoặc (subshell eval)nếu bạn muốn bảo vệ môi trường của bạn.
Cá nhân, tôi thích vỏ .dothơn tất cả.
printf 'var=something%d ; echo "$var"\n' `seq 1 5` | . /dev/fd/0
ĐẦU RA
something1
something2
something3
something4
something5
NHƯNG BẠN CÓ CẦN NÓ KHÔNG?
Nguyên nhân duy nhất để sử dụng một trong hai, thực sự là trong trường hợp biến của bạn thực sự gán hoặc đánh giá một cái khác, hoặc tách từ là quan trọng đối với đầu ra.
Ví dụ:
var='echo this is var' ; $var
ĐẦU RA:
this is var
Điều đó hoạt động, nhưng chỉ vì echokhông quan tâm đến số lượng đối số của nó.
var='echo "this is var"' ; $var
ĐẦU RA:
"this is var"
Xem? Các trích dẫn kép xuất hiện vì kết quả của việc mở rộng shell $varkhông được đánh giá quote-removal.
var='printf %s\\n "this is var"' ; $var
ĐẦU RA:
"this
is
var"
Nhưng với evalhoặc sh:
var='echo "this is var"' ; eval "$var" ; sh -c "$var"
ĐẦU RA:
this is var
this is var
Khi chúng ta sử dụng evalhoặc shshell sẽ vượt qua lần thứ hai với kết quả của việc mở rộng và đánh giá chúng là một lệnh tiềm năng, và vì vậy các trích dẫn tạo ra sự khác biệt. Bạn cũng có thể làm:
. <<VAR /dev/fd/0
${var:=echo "this is var"}
#END
VAR
ĐẦU RA
this is var
e='echo foo'; $ehoạt động tốt