BASH:在变量中存储嵌套的命令参数

时间:2013-07-05 02:27:01

标签: bash

这是我第一次使用真正的bash脚本,而且我在扩展和引用方面遇到了很大麻烦。

如果给出参数-t,我正在编写一个测试ssh连接和一些远程mysql命令的脚本,如果给出参数-r,则在真实的远程服务器上使用它们。我想将ssh和mysql命令的选项存储到变量中,因此当给出-r或-t时,它使用相同的例程。

长话短说,剧本或多或少看起来像这样:

sql="SELECT id FROM user WHERE (email LIKE '%a@b.com' OR email LIKE '%c@d.com');"

case "$1" in
  -t )
      ssh_opts=(localhost -i ~/.ssh/id_rsa)
      mysql_opts=(-u root --password=password test);;

  -r )
      ssh_opts=("-oCheckHostIP no" "-oCompression yes" "-oProtocol 2" "-oProxyCommand connect -4 -S localhost:9050 $(tor-resolve remoteip localhost:9050) 22" remoteip -i ~/.ssh/id_rsa -l httpd)
      mysql_opts=('-h mysqlserver' '-P 3306' '-u user' '--password=password' database) -t );;
esac


read -a ids < <(ssh "${ssh_opts[@]}" \"mysql "${mysql_opts[@]" --disable-column-names -B -e \"$'${sql}'\""\")
csv_ids=$(IFS=,; echo "${ids[*]}")

你可能已经注意到我在这一点上非常迷茫,我觉得这太复杂了。任何人都可以分享一些如何正确做到这一点的提示吗?

谢谢

1 个答案:

答案 0 :(得分:2)

在这部分之前,你的表现并不是那么糟糕:

read -a ids < <(ssh "${ssh_opts[@]}" \"mysql "${mysql_opts[@]" --disable-column-names -B -e \"$'${sql}'\""\")

要生成mysql命令,请使用printf %q引用它们,然后使用printf %q为您正确引用的字符串:

printf -v mysql_opts_str '%q ' "${mysql_opts[@]}"
ssh "${ssh_opts[@]}" "mysql $mysql_opts_str ..."

原始表单不起作用,因为\"foo bar\"被解析为两个参数:"foobar";转义时,引号被视为数据,而不是语法。


那就是说--bash通常是用于与SQL交互的错误工具;它不提供解析任意表内容的工具(因此您最终会对查询结果做出假设),也不提供将任意字符串作为绑定变量传递的工具。 (我曾经用这种支持编写了一个命令行Oracle客户端,供shell脚本使用,但它从未公开发布)。你应该认真考虑使用更适合这项工作的工具。