dumbmick
dumbmick

Reputation: 1

Why does this for loop not break out following timeout?

If the sent ssh command times out, i need it to move to next address in list It gets to where I send the pw, Stuff, and I need it to break out of that if it doesn't get in. It just hangs. Why?

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 "> "
}

Upvotes: 0

Views: 296

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137587

The expect command swallows break and continue conditions (as it thinks of itself internally as a loop). This means that you'd need to do:

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

However, it is probably easier to just refactor that code so that the whole interaction with a particular address is in a procedure, and then use 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
}

I find it much easier to then focus on how to make things work correctly for one host independently of making them work across a whole load of them. (For example, you don't clean up the connection before going onto the next when there's a timeout; this leaks a virtual terminal until the overall script exits.)

Upvotes: 1

Related Questions