【问题标题】:Proper escaping of quotes and parens when using expect, ssh, ant and mysqldump使用 expect、ssh、ant 和 mysqldump 时正确转义引号和括号
【发布时间】:2011-07-07 08:52:51
【问题描述】:

我们目前有一个可用的 ant 脚本,它将使用 mysqldump 将远程服务器上的数据库转储到该远程服务器上的文件中。我们使用 ant 的 exec 任务运行一个期望脚本来 ssh 到远程机器并运行 mysqldump 命令。我正在尝试更新命令以将转储限制为仅包含不到 3 个月的数据。我遇到了令人讨厌的引号和括号转义问题。

这是我正在尝试使用的命令行:

expect -f ssh-pass.exp <SERVER_PASSWD> ssh <USER>@<IP_ADDRESS> \"mysqldump -h localhost -u user --password=passwd staging --where=\"createTimeFi > now() - interval 3 month\" --ignore-table=staging.JMS_MESSAGES --ignore-table=staging.JMS_ROLES --ignore-table=staging.JMS_SUBSCRIPTIONS --ignore-table=staging.JMS_TRANSACTIONS --ignore-table=staging.JMS_USERS --ignore-table=staging.TIMERS > dump.sql\"

这里是期望脚本:

set password [lrange $argv 0 0]
set command [lrange $argv 1 1]
set arg1 [lrange $argv 2 2]
set arg2 [lrange $argv 3 end]
puts "command: $command"
puts "arg1: $arg1"
puts "arg2: $arg2"
set timeout -1
spawn $command $arg1 "$arg2"
match_max 100000
expect "*?assword:*"
puts "\rsending password..."
send -- "$password\r"
puts "\r**************** Running remote command, wait... ******************"
expect eof

我尝试了 ssh 命令和 mysqldump 的 where 参数的各种转义引号组合,但均未成功。有时expect会抱怨“interval”是一个未知的命令。有时在我的本地机器上,该命令会创建名为“now”或“dump.sql”的文件,这似乎表明我的本地 shell 正在吃引号并在不应该的地方进行重定向,否则它会抱怨无效令牌(即括号)。

【问题讨论】:

    标签: shell ant ssh mysqldump expect


    【解决方案1】:

    这不是 Expect 问题。它仅与 shell 引用有关。

    您需要将长长的 mysqldump 命令及其参数作为单个“单词”传递,因此您无法转义外部引号。并且您可以使用单引号作为外引号,这样您就不必转义内双引号。

    expect -f ssh-pass.exp &lt;SERVER_PASSWD&gt; ssh &lt;USER&gt;@&lt;IP_ADDRESS&gt; 'mysqldump -h localhost -u user --password=passwd staging --where="createTimeFi &gt; now() - interval 3 month" --ignore-table=staging.JMS_MESSAGES --ignore-table=staging.JMS_ROLES --ignore-table=staging.JMS_SUBSCRIPTIONS --ignore-table=staging.JMS_TRANSACTIONS --ignore-table=staging.JMS_USERS --ignore-table=staging.TIMERS &gt; dump.sql'

    ====

    更新:关于您的 Tcl 的一些说明(预期)

    1. 使用[lindex $argv 0] 而不是[lrange $argv 0 0]
    2. mysqlcommand 是用大括号发送的,因为您将它创建为一个列表 ([lrange $argv 3 end]),但它应该是单个字符串。既然您使用了正确的 shell 引用,[lindex $argv 3] 也可以解决这个问题。如果你不把它作为一个参数传递,那么set remote_command [join [lrange $argv 3 end]] 然后spawn $command $arg1 $arg2

    【讨论】:

    • 谢谢。这让我很接近。我不得不切换到使用 bash 而不是 zsh 并且我确实必须调整我的期望脚本,因为 mysqldump 命令被发送时带有花括号。
    • 请注意,在引号内,您还可以添加换行符和制表符缩进以使其可读。如果你真的疯了,你可以在一大堆引号中包含一个 200 行的脚本(这并不是一个好主意)。
    • @glennjackman 感谢有关使用 lindex 的提示 - 我的一些输入也得到了括号,这解决了 +1
    猜你喜欢
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 2013-07-07
    • 2011-01-26
    • 2014-05-03
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多