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 bash
theo 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ỏ .dot
hơ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ì echo
khô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 $var
không được đánh giá quote-removal
.
var='printf %s\\n "this is var"' ; $var
ĐẦU RA:
"this
is
var"
Nhưng với eval
hoặ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 eval
hoặc sh
shell 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'; $e
hoạt động tốt