2011-03-02 1 views
0

현재 원격 서버의 데이터베이스에 mysqldump를 사용하여 원격 서버의 파일을 덤프하는 ant 스크립트가 있습니다. ant의 exec 태스크를 사용하여 원격 머신으로 ssh하기위한 expect 스크립트를 실행하고 mysqldump 명령어를 실행한다. 3 개월 미만의 데이터 만 포함하도록 덤프를 제한하는 명령을 업데이트하려고합니다. 나는 성가신 이스케이프 문제를 따옴표와 괄호로 달리고있다. 기대 스크립트 여기expect, ssh, ant 및 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\" 

한다 : 나는 ssh 명령 주위에 탈출 따옴표의 다양한 조합을 시도했습니다

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 

여기

내가 작업을 얻으려고 명령 줄입니다 mysqldump의 where 인수는 성공하지 못한다. 때때로 "간격"은 알 수없는 명령이라고 불평 할 것입니다. 가끔 내 로컬 컴퓨터에서 명령은 "now"또는 "dump.sql"이라는 파일을 생성하여 내 로컬 쉘이 따옴표를 먹어서는 안되며 잘못된 토큰에 대해 불평 할 리디렉션을 수행하는 것으로 나타납니다 (즉, parens).

답변

2

이것은 예상치 못한 문제가 아닙니다. 쉘 인용에만 관련이 있습니다.

긴 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에 대한 몇 가지 메모를 작성하기 때문에 mysqlcommand가 괄호로 전송 된

  1. 사용 [lindex $argv 0] 대신 [lrange $argv 0 0]
  2. 의 (예상) 그것은 목록 ([lrange $argv 3 end])이지만 단일 문자열이어야합니다. 이제 적절한 셸 인용 부호를 사용하고 있으므로 [lindex $argv 3]으로 충분하므로이 문제도 해결할 수 있습니다. 하나의 인수로 예상대로 전달하지 않으면 set remote_command [join [lrange $argv 3 end]] 다음 spawn $command $arg1 $arg2
+0

감사합니다. 이것은 나를 가까이있게했다. 나는 zsh 대신에 bash를 사용해야만했고, mysqldump 명령이 중괄호로 보내지기 때문에 기대하는 스크립트를 수정해야했다. – Nate

+1

@ 네이트, 귀하의 의견을 답변하기 위해 답변으로 업데이트했습니다. –

+0

따옴표 안에 개행과 탭 들여 쓰기를 추가하여 읽을 수 있도록 할 수 있습니다. 실제로 열매 맺는다면 큰 따옴표 세트 안에 200 줄짜리 스크립트가있을 수 있습니다 (항상 좋은 생각은 아닙니다). –

관련 문제