1

ファイルで tcl send expect スクリプトを実行し、./file として実行します。

#!/usr/bin/expect
spawn -noecho telnet 42.0.1.11
set timeout 900
expect "login:"
send "admin\r"
expect "Password: "
send "ram\r"
expect "#"
for {set i 0} {$i <= 1000000000} {incr i} {
 some router commands
}

これは、ルーターがリロードされるまで正常に機能します。ルーターがリロードされると、このスクリプトは spawn id が開いていないため停止します。スクリプトを再開したい (ほとんどの場合、リロードにかかる時間は変動するため、リロードにかかる正確な時間はわかりません)。スクリプトを自動的に再開する方法

ありがとう

4

1 に答える 1

0

ログイン プロシージャを proc にラップし、EOF を取得した場合は再度呼び出します。これが基本的な考え方です。ただし、問題が発生する他の方法がある可能性があることを覚えておいてください。

編集:いくつかの調査の後、コードを書き直しました。これは Linux でテストされており、「ルーターの再起動」が Solaris 10 ワークステーションによってシミュレートされています (ここで再起動する Cisco はありません)。前述したように、ping実装は OS ごとに異なるproc Pingため、状況に合わせて変更する必要がある場合があります。

#!/usr/bin/tclsh

package require Expect

proc RouterLogin {ip user pass} {
    spawn -noecho telnet $ip
    set timeout 60
    expect "login:"
    send "$user\r"
    expect "Password: "
    send "$pass\r"
    expect "#"
    return $spawn_id
}

proc RouterPing ip {
    # ping retry limit      - 3
    # delay between retries - 30 seconds
    set limit   3
    set delay   30
    set attempt 1
    set result false
    while {$result == false && $attempt <= $limit} {
        set result [Ping $ip]
        incr attempt
        if {!$result && $attempt <= $limit} {
            # wait $delay seconds
            after [expr {1000 * $delay}]
        }
    }
    return $result
}

proc Ping ip {
    set pingCmd "ping -c 1 $ip"
    catch {eval exec $pingCmd} pingRes
    if {[regexp "bytes from" $pingRes]} {
        return true
    } else {
        return false
    }
}

proc RouterExec {ip user pass commandList} {
    set spawn_id [RouterLogin $ip $user $pass]
    set timeout 30
    foreach cmd $commandList {
        send "$cmd\r"
        expect {
            "#" {
                # you are good
                puts "Command executed successfully"
            }
            eof {
                # wait 5 minutes
                after [expr {1000 * 60 * 5}]
                if {[RouterPing $ip]} {
                    # ping was successful, relogin and resume
                    set spawn_id [RouterLogin $ip $user $pass]
                } else {
                    # ping was not successful, abort execution
                    return false
                }
            }
            timeout {
                puts "INF: timeout"
                return false
            }
        }
    }
    send "logout\r"
    return true
}

set commandList [list command1 command2 command3]

RouterExec "42.0.1.11" "admin" "ram" $commandList
于 2013-01-21T20:04:38.673 に答える