期望在第一次迭代后在 foreach 中卡住

Expect getting stuck when inside a foreach after first iteration

第一次迭代后输出卡住。当循环中只存在一个 expect 时工作正常。使用 exp_continue 时也会失败。

#!/usr/bin/expect -f

exp_internal 1
set timeout -1
set passwords [list foo bar test]
set connected false
set passwordUsed "test"
spawn ssh -oHostKeyAlgorithms=+ssh-dss root@192.168.1.136 -y

foreach i $passwords {
    expect "assword:" { send -- "$i\r";}
    expect "asd" {send "test"}
}  
expect eof

输出:

spawn ssh -oHostKeyAlgorithms=+ssh-dss root@192.168.1.136 -y



root@192.168.1.136's password: 



root@192.168.1.136's password: 

调试

parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {1937}

expect: does "" (spawn_id exp4) match glob pattern "assword:"? no

expect: does "\r" (spawn_id exp4) match glob pattern "assword:"? no

expect: does "\rroot@192.168.1.136's password: " (spawn_id exp4) match glob pattern "assword:"? yes
expect: set expect_out(0,string) "assword:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\rroot@192.168.1.136's password:"
send: sending "foo\r" to { exp4 }

expect: does " " (spawn_id exp4) match glob pattern "asd"? no

expect: does " \r\n" (spawn_id exp4) match glob pattern "asd"? no

expect: does " \r\n\rroot@192.168.1.136's password: " (spawn_id exp4) match glob pattern "asd"? no

然后挂在最后一个expect上。

超时值是问题所在:expect 一直在等待看到“asd”

你需要这样的东西(未经测试)

set passwords {foo bar baz}
set idx 0
spawn ...
expect {
    "assword:" {
        if {$idx == [llength $passwords]} {
            error "none of the passwords succeeded"
        }
        send "[lindex $passwords $idx]\r"
        incr idx
        exp_continue
    }
    "asd" {send "test"}
}
expect eof

exp_continueexpect 命令中循环等待“asd”或“assword”再次出现。

“asd”案例不使用exp_continue,所以在发送“test”后,this期待表扬结束。