Mọi người đều nói eval là xấu, và bạn nên sử dụng $() làm người thay thế. Nhưng tôi đã gặp phải tình huống trong đó unquoting không được xử lý giống nhau bên trong $().
Bối cảnh là tôi đã bị đốt cháy quá thường xuyên bởi các đường dẫn tệp có khoảng trống trong chúng và do đó, để trích dẫn tất cả các đường dẫn như vậy. Nhiều hoang tưởng hơn về việc muốn biết tất cả các tập tin thực thi của tôi đến từ đâu. Thậm chí hoang tưởng hơn, không tin tưởng bản thân mình, và vì vậy giống như có thể hiển thị các lệnh đã tạo mà tôi sắp chạy.
Dưới đây tôi cố gắng biến thể về việc sử dụng eval so với $(), và cho dù tên lệnh được trích dẫn (cuz nó thể chứa khoảng trắng)
BIN_LS="/bin/ls"
thefile="arf"
thecmd="\"${BIN_LS}\" -ld -- \"${thefile}\""
echo -e "\n Running command '${thecmd}'"
$($thecmd)
Running command '"/bin/ls" -ld -- "arf"'
./foo.sh: line 8: "/bin/ls": No such file or directory
echo -e "\n Eval'ing command '${thecmd}'"
eval $thecmd
Eval'ing command '"/bin/ls" -ld -- "arf"'
/bin/ls: cannot access arf: No such file or directory
thecmd="${BIN_LS} -ld -- \"${thefile}\""
echo -e "\n Running command '${thecmd}'"
$($thecmd)
Running command '/bin/ls -ld -- "arf"'
/bin/ls: cannot access "arf": No such file or directory
echo -e "\n Eval'ing command '${thecmd}'"
eval $thecmd
Eval'ing command '/bin/ls -ld -- "arf"'
/bin/ls: cannot access arf: No such file or directory
$("/bin/ls" -ld -- "${thefile}")
/bin/ls: cannot access arf: No such file or directory
Vì vậy ... đây là khó hiểu. Đường dẫn lệnh được trích dẫn là hợp lệ ở mọi nơi ngoại trừ bên trong một cấu trúc $()? Ví dụ ngắn hơn, trực tiếp hơn:
$ c="\"/bin/ls\" arf"
$ $($c)
-bash: "/bin/ls": No such file or directory
$ eval $c
/bin/ls: cannot access arf: No such file or directory
$ $("/bin/ls" arf)
/bin/ls: cannot access arf: No such file or directory
$ "/bin/ls" arf
/bin/ls: cannot access arf: No such file or directory
Làm cách nào giải thích trường hợp đơn giản $($c)
?
Chuỗi không được kiểm duyệt sẽ được đánh giá ngay lập tức. c = ("/ bin/ls"/bin/l *) thực hiện điều gì đó khá khác so với mong muốn. (nhìn với echo "'$ {c [@]}'") c = ("/ bin/ls" "/ bin/l *") thì z = $ ("$ {c [@]}") không thành công. Một mảng các đối số không thể được sử dụng độc đáo với $()? – Shenme
Tuy nhiên, c = ("/ bin/ls" "/ bin/l *") thì z = $ ($ {c [@]}) có vẻ hoạt động tốt. Đây có phải là biểu mẫu thực thi $() mà bạn muốn chỉ cho tôi không? – Shenme