命令不使用Expect写入缓冲区

时间:2010-05-31 09:00:34

标签: expect

我尝试使用expect脚本备份Linkproof设备,但我遇到了一些麻烦。这是我期待的第一个剧本,我已达到我的极限;)

#!/usr/bin/expect
spawn ssh @IPADDRESS
expect "username:"
# Send the username, and then wait for a password prompt.
send "@username\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "@password\r"
expect "#"
# Send the prebuilt command, and then wait for another shell prompt.
send "system config immediate\r"
#Send space to pass the pause
expect -re "^ *--More--\[^\n\r]*"
send ""
expect -re "^ *--More--\[^\n\r]*"
send ""
expect -re "^ *--More--\[^\n\r]*"
send ""
# Capture the results of the command into a variable. This can be displayed, or written to disk.
sleep 10
expect -re .*
set results $expect_out(buffer)
# Copy buffer in a file
set config [open linkproof.txt w]
puts $config $results
close $config
# Exit the session.
expect "#"
send "logout\r"
expect eof

输出文件的内容:

无法建立主机'@IP(XXX.XXX.XXX.XXX)'的真实性。

RSA密钥指纹为XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX。

您确定要继续连接(是/否)吗? @username

请输入“是”或“否”:@ password

请输入“是”或“否”:系统配置立即

请输入“是”或“否”:


您可以看到,该命令的结果不在文件中。请你帮我理解为什么? 谢谢你的帮助。

罗穆亚尔德

2 个答案:

答案 0 :(得分:3)

所有“期望”语句都超时,因为他们正在等待的文本与实际显示的文本不匹配。让我们来看看前两个,其他的都是一样的。

你说:

expect "username:"

但它从ssh实际收到的是:

The authenticity of host '@IP (XXX.XXX.XXX.XXX)' can't be established.
RSA key fingerprint is XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.
Are you sure you want to continue connecting (yes/no)?

这不包含字符串“username:”,因此expect命令将超时,脚本将继续执行下一个命令:

send "@username\r"

我们可以看到它确实发送了:

Are you sure you want to continue connecting (yes/no)? @username

但这不是这个问题的有效答案。

其余的输出反复出现同样的想法。

答案 1 :(得分:1)

正如@joefis所提到的,你需要从ssh中捕获是/否。

我在serverexchange中的回复中将其复制为高度相关的

  

如果您监控字符串,则需要避免使用“密码:”   在登录期间,您会发现它并不总是大写。

     

将你的期望改为-re“(。*)assword:”或“assword:”往往是   更有效地抓住这条线。

     

如果您发现时间仍然太快,您可以睡一觉   1;在发送之前

     

这是我用于期待的东西

expect {
    #When asked about authenticity, answer yes then restart expect block
    "(yes/no)?" { 
        send "yes\n"
        exp_continue 
    }
    "passphrase" { send "\r" }
    -re "(.*)assword:"  { sleep 1; send -- "password\r" }
    -re $prompt { return }
    timeout     { puts "un-able to login: timeout\n"; return }
    eof         { puts "Closed\n" ; return }
}

所以有一些事情,这将允许期望在单个期望上响应任何这些结果,如果找到return语句,它将仅继续更多的代码。我建议设置一个提示值,因为它变得有帮助,以检测您的命令是否完整或您的登录确实成功。