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
最初の区切り線を削除する必要があります。 1つの方法は次のとおりです。
if {![regexp {^.+?\r\n(.*)$} $cmd_output -> filename]} {
error "unexpected output: does not contain \\r\\n"
}
# now, go get $filename