期望脚本使用 grep 从远程服务器下载最新文件

期望脚本使用 grep 从远程服务器下载最新文件

我有一个expect脚本可以从远程服务器下载最新的数据库备份。我是 shell/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将包含您发送的 shell 命令以及输出,所有行均以\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

相关内容