为什么这会让脚本不断产生ssh命令,从不打印“睡觉”或“睡眠不足”,从不睡觉?
我的目的是尝试ssh'ing,如果它看到“password:”退出while循环(这里没有看到更多的代码将包含一个交互。)如果3秒过去,或ssh在此之前死亡,它应该放,睡3秒,再放,然后再尝试ssh。
主机名“doesntexist”用于强制失败,例如名称或服务未知。
#!/usr/bin/expect -f
set readyForPassword 0
while { $readyForPassword == 0 } {
spawn ssh nouser@doesntexist
expect -timeout 3 {
"password: " {
set readyForPassword 1
} timeout {
puts "going to sleep"
sleep 3
puts "out of sleep"
} eof {
puts "going to sleep"
sleep 3
puts "out of sleep"
}
}
}
答案 0 :(得分:3)
使用-timeout
标志时,它应该在Expect
模式之前,而不是在操作上。
通过调试,我们可以发现Expect
与您现有代码所采用的模式是,
expect: does "" (spawn_id exp6) match glob pattern "\n "password: " {\n set readyForPassword 1\n } timeout {\n puts "going to sleep"\n sleep 3\n puts "out of sleep"\n } eof {\n puts "going to sleep"\n sleep 3\n puts "out of sleep"\n }\n "? no
在Exploring Expect一书的第76页,我们可以看到以下陈述,
那时出了什么问题?初始打开括号会导致Tcl继续扫描 用于完成命令的行。找到匹配的括号后,全部 外括号之间的模式和动作传递给 期待作为参数
-timeout
不是动作,只是一个标志。 Expect假设以下为模式
"password: " {
set readyForPassword 1
} timeout {
puts "going to sleep"
sleep 3
puts "out of sleep"
} eof {
puts "going to sleep"
sleep 3
puts "out of sleep"
}
请记住,Expect
并不强制执行该操作,只有模式,即它会表现为我们只喜欢模式,但不采取任何行动。
简单地说,您的代码与
相同expect "Hello"; # Either 'timeout' or pattern can be matched. But, no action at all
您的代码应重新安排为,
#!/usr/bin/expect -d
set readyForPassword 0
while { $readyForPassword == 0 } {
spawn ssh nouser@doesntexist
expect {
-timeout 3 "password: " {set readyForPassword 1}
timeout {
puts "going to sleep in timeout"
sleep 3
puts "out of sleep in timeout"
} eof {
puts "going to sleep in eof"
sleep 3
puts "out of sleep in eof"
}
}
}