为什么这不期望句柄超时或eof
Why doesn't this expect handle timeout or eof
为什么这个 expect 脚本不断生成 ssh 命令,从不打印 "going to sleep" 或 "out of sleep",也从不休眠?
我的意图是尝试 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"
}
}
}
当使用-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页,我们可以看到下面的语句,
The initial open brace causes Tcl to continue scanning additional
lines to complete the command. Once the matching brace is found, all
of the patterns and actions between the outer braces are passed to
expect as arguments
那到底出了什么问题?
-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"
}
}
}
为什么这个 expect 脚本不断生成 ssh 命令,从不打印 "going to sleep" 或 "out of sleep",也从不休眠?
我的意图是尝试 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"
}
}
}
当使用-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页,我们可以看到下面的语句,
The initial open brace causes Tcl to continue scanning additional lines to complete the command. Once the matching brace is found, all of the patterns and actions between the outer braces are passed to expect as arguments
那到底出了什么问题?
-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"
}
}
}