为什么这不期望句柄超时或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"
        }
   }
}