Правильное экранирование кавычек и паренов при использовании ожидаемых, ssh, ant и mysqldump - PullRequest
0 голосов
/ 02 марта 2011

В настоящее время у нас есть рабочий скрипт ant, который будет использовать mysqldump для выгрузки базы данных на удаленном сервере в файл на этом удаленном сервере.Мы используем задачу 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 и аргумента where для mysqldump безуспешно.Иногда ожидающие будут жаловаться, что «интервал» - неизвестная команда.Иногда на моем локальном компьютере команда создает файлы с именем "now" или "dump.sql", которые, кажется, указывают на то, что моя локальная оболочка ест кавычки и выполняет перенаправления, куда не следует, или будет жаловаться на недопустимые токены (т.е.круглые скобки).

1 Ответ

2 голосов
/ 02 марта 2011

Это не ожидаемая проблема. Это связано только с цитированием оболочки.

Вам нужно передать эту длинную команду mysqldump и ее аргументы как одно «слово», чтобы вы не могли избежать внешних кавычек. И вы можете использовать одинарные кавычки в качестве внешних кавычек, поэтому вам не нужно избегать внутренних двойных кавычек.

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'

====

обновление: некоторые заметки о вашем Tcl (ожидаемо)

  1. используйте [lindex $argv 0] вместо [lrange $argv 0 0]
  2. команда mysql была отправлена ​​с фигурными скобками, потому что вы создаете ее как список ([lrange $argv 3 end]), но она должна быть одной строкой. Теперь, когда вы используете правильное цитирование оболочки, [lindex $argv 3] будет достаточно, и эта проблема также решена. Если вы не передаете его как один аргумент, то set remote_command [join [lrange $argv 3 end]], а затем spawn $command $arg1 $arg2
...