每个人都说 eval 是邪恶的,你应该使用 $() 作为替代。但是我遇到了这样一种情况,即在 $()中对取消引用的处理方式不同。
背景是我经常被带有空格的文件路径烧伤,所以喜欢引用所有这些路径。更想知道我所有的可执行文件来自哪里的偏执狂。更偏执,不相信自己,所以喜欢能够显示我将要运行的创建的命令。
下面我尝试使用 eval 与 $() 的变化,以及命令名称是否被引用(因为它可能包含空格)
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
所以......这令人困惑。除了 $() 构造之外,带引号的命令路径在任何地方都有效吗?一个更短、更直接的例子:
$ 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
如何解释这个简单的 $($c)
案例?