expect
원격 서버에서 최신 데이터베이스 백업을 다운로드하는 스크립트가 있습니다 . 저는 쉘/예상 스크립팅을 처음 접했고 출력 버퍼의 깨끗한 파일 이름을 변수에 저장하는 데 어려움을 겪고 있습니다. 이것이 내가 지금까지 얻은 것입니다:
#!/usr/bin/expect -f
set dbname [lindex $argv 0]
spawn ssh "sshuser@remote_ip"
expect "password: "
send "MySSHPass\r"
expect "$ "
send "cd /var/backup/dumps\r"
expect "$ "
send "ls -tl | grep --color=never -o -m1 \"\\<$dbname.*\\>\"\r"
expect "\r" # flushing the previous output from the buffer done right?
expect ".gz"
# the resulting string seems to have a leading newline or return char
set filename $expect_out(buffer)
expect "$ "
send "exit\r"
spawn sftp "sshuser@remote_ip"
expect "password:"
send "MySSHPass\r"
expect "sftp>"
send "lcd database_dumps\r"
expect "sftp>"
send "get /var/backup/dumps/$filename\r"
expect "sftp>"
send "exit\r"
추출된 파일 이름에 개행 문자나 반환 문자가 있는 것 같아서 sftp 가져오기 경로가 올바르게 연결되지 않았습니다. 이를 올바르게 수행하는 방법에 대한 제안 사항이 있습니까?
답변1
grep
첫 번째 요점은 출력이 필요하지 않다는 것입니다 ls
. 이 정도면 충분합니다.
send "ls -1t $dbname.*\r"
최신 정보를 얻으세요:
send "ls -1t $dbname.* | head -1\r"
이제 질문으로 돌아가겠습니다. 예, Expect_out 버퍼에서 명령 출력을 추출하는 것은 번거로울 수 있습니다. 이 작업을 수행:
expect -re {(.*)\r\n$ $}
set cmd_output $expect_out(1,string)
cmd_output
출력과 함께 보낸 쉘 명령이 포함되며, 로 시작하는 모든 줄을 \r\n
확인할 수 있습니다.
exec od -c <<$expect_out(buffer)
\r\n
첫 번째 구분선을 제거해야 합니다 . 한 가지 방법은 다음과 같습니다.
if {![regexp {^.+?\r\n(.*)$} $cmd_output -> filename]} {
error "unexpected output: does not contain \\r\\n"
}
# now, go get $filename