使用期望关闭会话

时间:2016-06-28 21:41:04

标签: ssh tcl 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};
       }

提前致谢

1 个答案:

答案 0 :(得分:1)

编写期望脚本时,您需要按照expect远程端的模式编写一些输出(例如,提示),然后send回复一些内容。整体模式为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选项与提示完全匹配,因为这在我的测试中效果更好; 您可能需要它,或者可能不需要。

此外,请确保在使用\r发送的行末尾使用send,否则另一方仍将等待“按返回”这是\r模拟的内容。并且不要忘记使用:

exp_internal 1

在调试代码时,它会告诉您完全期望的内容。