为什么这个for循环不会在超时后中断?

时间:2014-07-15 09:26:42

标签: tcl expect

如果发送的ssh命令超时,我需要它移动到列表中的下一个地址 它到达我发送pw,Stuff的地方,我需要它来突破它,如果它没有 进来。它只是挂起。为什么呢?

foreach address $perAddress {

        set timeout 10
        send "ssh $address user someone\r"
        expect "word:" 
        send "Stuff\r"
        expect {
                "prompt*#" {continue}
                timeout {break}
        }
        set perLine [split $fileData "\n"]
        set timeout 600
        foreach line $perLine {
                send "$line\r"
                expect "# "
        }
        send "exit\r"
        expect "> "
}

1 个答案:

答案 0 :(得分:1)

expect命令吞下breakcontinue条件(因为它在内部将其视为循环)。这意味着您需要这样做:

set timedOut 0
expect {
    "prompt*#" {
        # Do nothing here
    }
    timeout {
        set timedOut 1
    }
}
if {$timedOut} break

但是,重构该代码可能更容易,以便与特定地址的整个交互在一个过程中,然后使用return

proc talkToHost {address} {
    global fileData
    set timeout 10
    send "ssh $address user someone\r"
    expect "word:" 
    send "Stuff\r"
    expect {
        "prompt*#" {continue}
        timeout {return}
    }
    set perLine [split $fileData "\n"]
    set timeout 600
    foreach line $perLine {
        send "$line\r"
        expect "# "
    }
    send "exit\r"
    expect "> "
}

foreach address $perAddress {
    talkToHost $address
}

我发现更容易关注如何使一个主机正常工作,而不是让它们在整个主机上工作。 (例如,在超时之前进入下一个连接之前,您不会清理连接;这会泄漏虚拟终端,直到整个脚本退出。)