我有一个bash变量:
A="test; ls"
我想将它用作通话的一部分:
echo $A
我希望它能扩展到:
echo test; ls
然而,它已扩展:
echo "test;" "ls"
如何实现我想要的目标?我能想到的唯一解决方案是:
bash -c "echo $A"
也许有更优雅的东西?
答案 0 :(得分:3)
如果你正在构建复合命令,运行重定向等,那么你需要使用eval:
A="test; ls"
eval "$A"
然而,更好不要这样做。遵循良好实践的典型用例如下:
my_cmd=( something --some-arg "another argument with spaces" )
if [[ $foo ]]; then
my_cmd+=( --foo="$foo" )
fi
"${my_cmd[@]}"
与eval
版本不同,它只能运行一个命令行,并且会完全按照给定的方式运行 - 这意味着即使foo='$(rm -rf /)'
您未获得硬盘驱动器擦拭。 :)
如果您绝对必须使用eval
,或者正在形成一个shell命令,以便在必须进行shell评估的上下文中使用(例如,在ssh
命令行上传递),您可以使用printf %q
来实现一种混合方法,以形成对eval安全的命令行:
printf -v cmd_str 'ls -l %q; exit 1' "some potentially malicious string"
eval "$cmd_str"
有关eval
命令的更多详细信息以及为什么应该非常小心地使用它,请参阅BashFAQ #48,或BashFAQ #50查看有关以编程方式构建命令的陷阱和最佳实践的一般性讨论。 (请注意,bash -c "$cmd_str"
在安全影响方面与eval相当,并且需要采取相同的预防措施才能安全使用。
答案 1 :(得分:-1)
不要使用echo,只需要var
A="echo test; ls"
$A