如何从变量构建bash命令?

时间:2014-07-08 20:25:19

标签: bash

我有一个bash变量:

A="test; ls"

我想将它用作通话的一部分:

echo $A

我希望它能扩展到:

echo test; ls

然而,它已扩展:

echo "test;" "ls"

如何实现我想要的目标?我能想到的唯一解决方案是:

bash -c "echo $A"

也许有更优雅的东西?

2 个答案:

答案 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