使用期望关闭会话在远程服务器中复制 3 个最新文件

copy 3 newest files in remote server using expect the close the session

首先,对于 expect 脚本,我是一个完全的新手。我已经编写了一些 ssh 脚本,但我似乎无法弄清楚如何在 运行 新版本的一组测试之后获取最新的 3 个日志文件。我的主要目标是找到最新的日志文件并将它们复制到我的本地机器上。请不要告诉我硬编码登录名和密码是不好的做法,我这样做是因为让脚本正常工作是暂时的。我的代码目前...

#!/usr/bin/expect -f

set timeout 15

set prompt {\]$ ?#}

spawn ssh -o "StrictHostKeyChecking no" "root@remote_ip"
expect {
    "RSA key fingerprint" {send "yes\r"; exp_continue}
    "assword:" {send "password\r"; exp_continue}

}
sleep 15
send -- "export DISPLAY=<display_ip>\r"
sleep 5
send "cd /path/to/test/\r"
sleep 5
set timeout -1
send "bash run.sh acceptance.test\r"
#Everything above all works. The tests has finished, about to cp log files
send "cd Log\r"
sleep 5
send -- "pwd\r"
sleep 5
set newestFile [send "ls -t | head -3"]
#tried [eval exec `ls -t | head -3`]
#No matter what I try, my code always gets stuck here. Either it wont close the session 
#or ls: invalid option -- '|' or just nothing and it closes the session.
#usually never makes it beyond here :(
expect $prompt
sleep 5
puts $newestFile
sleep 5
send -- "exit\r"
sleep 5
set timeout 120
spawn rsync -azP root@remote_ip:'ls -t /logs/path/ | head -3' /local/path/
expect {
        "fingerprint" {send "yes\r"; exp_continue};
        "assword:" {send "password\r"; exp_continue};
       }

提前致谢

在编写 expect 脚本时,您需要遵循 expecting 远程端写入一些输出(例如,提示)然后 sending 一些内容作为回复的模式.总体格局为spawnexpectsendexpectsend、……、closewait。如果您不时 expect,有些缓冲区会被填满,这可能就是您遇到的情况。

让我们修复有问题的部分(尽管您也应该期待在此之前的提示):

send "cd Log\r"
expect -ex $prompt
send -- "pwd\r"
expect -ex $prompt
send "ls -t | head -3\r"
# Initialise a variable to hold the list of files produced
set newestFiles {}
# SKIP OVER THE LINE "TYPED IN" JUST ABOVE
expect \n
expect {
    -re {^([^\r\n]*)\r\n} {
        lappend newestFiles $expect_out(1,string)
        exp_continue
    }
    -ex $prompt
}
# Prove what we've found for demonstration purposes
send_user "Found these files: \[[join $newestFiles ,]\]\n"

我还进行了其他一些更正。特别是,send 本身没有有用的结果,所以我们需要一个带有正则表达式的 expect(使用 -re 标志)来挑选文件名。为此,我喜欢使用 expect 命令的另一种形式,因为这样我可以同时匹配多个对象。 (我使用 -ex 选项与提示进行精确匹配,因为这在我的测试中效果更好;您可能需要它,也可能不需要。

此外,请确保在使用 send 发送的行的末尾使用 \r,否则对方仍会等待“等待您按 Return”,这是 \r 模拟的。并且不要忘记使用:

exp_internal 1

在调试您的代码时,这会告诉您确切地期望是什么。