11.1. タイムアウト処理
いよいよマクロも複雑になり、例外処理が必要な状況になってきました。 例外処理というのは簡単に言うと、「変な事が起きた時の動作」ということになります。 プログラムやマクロはいつもいつも想定通りに動くとは限らず、結構な確率で変な事が起きるのです。 結構な確率で変なことが起きるくせに、変な事が起きるたびにマクロが止まっていたのでは、どうしようもありません。 そこで、例外処理というのが必要になってきます。
11.1.1. タイムアウトとは
タイムアウトとは、「今やってることを諦める」という動作のことを言います。 例えば、
wait "#"
というコマンドを書いていた場合、画面上に#が現れなかったり、取りこぼしたりしてしまうと、マクロはずっとwait “#”で止まってしまいます。 止まってしまうといつまでも次の処理には進めないので、マクロも停止せざるをえません。 それだと効率が悪いので、「ある程度の時間が経つと諦めていいよ」というのをマクロに教えるのがタイムアウトです。
11.1.2. タイムアウトのコマンド
タイムアウトは非常に簡単に書くことができます。
timeout=秒数
これで、秒数分の時間が経過したら次の処理に行きなさいね、ということをマクロに教えることができます。 ただし、タイムアウトを認識してくれるコマンドは限られていて、wait系のコマンドか、 recvlnコマンドだけです。 以下が、timeoutを認識するコマンドです。 recvln, wait, wait4all, waitevent, waitn, waitln, waitrecv, waitregex
11.2. タイムアウトを入れる
それでは、実際に例外を起こして、タイムアウトの動作を見てみたいと思います。
11.2.1. タイムアウトがないときの動作
まずは、timeoutを入れずに、「変なこと」を人為的に起こして、どうなるかを見てみたいと思います。 下記はこれまでに作成したマクロです。
;================================= ;yesnoboxの表示 ;================================= yesnobox 'マクロを開始しますか?' 'Logging' if result=0 then end endif ;================================= ;22ならSSH、その他ならそのポート番号にtelnet ;USER変数にSSH様のusernameを書きます ;================================= PORT=23 USER='sshuser' ;================================= ;fileopenでlist.txtを開き、FHに格納 ;================================= fileopen FH 'list.txt' 0 ;================================= ;whileでループを開始する ;================================= while 1 ;================================= ;filereadlnでFHから読み出し ;LINEに格納 ;================================= filereadln FH LINE ;================================= ;ifを使って、ファイルの最後まで来たら、 ;マクロのループから抜ける ;================================= if result=1 then break endif ;================================= ;LINEにIPアドレスが格納されたので、 ;LINEをIP_ADDRに代入する ;================================= IP_ADDR = LINE ;================================= ;変数格納 ;================================= PWD = 'ciscoshun' ;================================= ;PORTに22が書いてあれば、SSH ;elseはその番号に応じてtelnet ;PORTの型は整数なので、 ;int2str関数で文字列に変換し ;PORT_STR変数に格納する ;================================= if PORT=22 then strconcat IP_ADDR ' /ssh /auth=password /user=' strconcat IP_ADDR USER strconcat IP_ADDR ' /passwd=' strconcat IP_ADDR PWD connect IP_ADDR else strconcat IP_ADDR ':' int2str PORT_STR PORT strconcat IP_ADDR PORT_STR strconcat IP_ADDR ' /nossh /T=1' connect IP_ADDR wait 'Password:' sendln PWD endif ;================================= ;telnet接続、ログ保存ディレクトリ ;================================= getdir DIR changedir DIR ;================================= ;ログ保存名の確定 ;================================= getdate DATE '%Y%m%d-%H%M%S.log' SHRUN = 'show_run_' SHLOG = 'show_log_' strconcat SHRUN DATE strconcat SHLOG DATE ;================================= ;show runのログを取得 ;================================= logopen SHRUN 0 0 wait '<' pause 3 sendln 'en' wait 'Password' pause 3 sendln PWD wait '#' pause 3 sendln 'terminal length 0' wait '#' pause 3 sendln 'show run' pause 5 sendln '' wait '#' logclose ;================================= ;show logのログを取得 ;================================= logopen SHLOG 0 0 sendln 'show log' pause 5 sendln '' wait '#' sendln 'exit' logclose pause 5 ;================================= ;ここでループ元に戻る ;================================= endwhile ;================================= ;FHを無効化する ;================================= fileclose FH ;================================= ;messageboxの使用 ;================================= messagebox 'Successfully Done' 'Logging' end
96行目で
wait '>'
で>が表示されるのを待っています。 ここでわざと、表示されるはずのない<を待ってみることにします。 以下のように書き換えてみます。
wait '<'
これで、実際に動かしてみましょう。

この画像のように、ずーっと
wait '<'
のままで停止しています。 これは、マクロが表示されるはずのない<を永久に待とうとしているからです。 これでルータがtelnetタイムアウトをしてくれば、エラーとなって処理が終了することになります。
11.2.2. タイムアウトを投入
では、実際にtimeout処理をマクロに組み込んでみます。 今回はタイムアウトまでの時間を10秒に設定します。 先ほどのずーっと待つ状態と比べてどうなるかを見てみます。
;================================= ;timeoutを10秒に設定 ;================================= timeout=10 ;================================= ;yesnoboxの表示 ;================================= yesnobox 'マクロを開始しますか?' 'Logging' if result=0 then end endif ;================================= ;22ならSSH、その他ならそのポート番号にtelnet ;USER変数にSSH様のusernameを書きます ;================================= PORT=23 USER='sshuser' ;================================= ;fileopenでlist.txtを開き、FHに格納 ;================================= fileopen FH 'list.txt' 0 ;================================= ;whileでループを開始する ;================================= while 1 ;================================= ;filereadlnでFHから読み出し ;LINEに格納 ;================================= filereadln FH LINE ;================================= ;ifを使って、ファイルの最後まで来たら、 ;マクロのループから抜ける ;================================= if result=1 then break endif ;================================= ;LINEにIPアドレスが格納されたので、 ;LINEをIP_ADDRに代入する ;================================= IP_ADDR = LINE ;================================= ;変数格納 ;================================= PWD = 'ciscoshun' ;================================= ;PORTに22が書いてあれば、SSH ;elseはその番号に応じてtelnet ;PORTの型は整数なので、 ;int2str関数で文字列に変換し ;PORT_STR変数に格納する ;================================= if PORT=22 then strconcat IP_ADDR ' /ssh /auth=password /user=' strconcat IP_ADDR USER strconcat IP_ADDR ' /passwd=' strconcat IP_ADDR PWD connect IP_ADDR else strconcat IP_ADDR ':' int2str PORT_STR PORT strconcat IP_ADDR PORT_STR strconcat IP_ADDR ' /nossh /T=1' connect IP_ADDR wait 'Password:' sendln PWD endif ;================================= ;telnet接続、ログ保存ディレクトリ ;================================= getdir DIR changedir DIR ;================================= ;ログ保存名の確定 ;================================= getdate DATE '%Y%m%d-%H%M%S.log' SHRUN = 'show_run_' SHLOG = 'show_log_' strconcat SHRUN DATE strconcat SHLOG DATE ;================================= ;show runのログを取得 ;================================= logopen SHRUN 0 0 wait '<' pause 3 sendln 'en' wait 'Password' pause 3 sendln PWD wait '#' pause 3 sendln 'terminal length 0' wait '#' pause 3 sendln 'show run' pause 5 sendln '' wait '#' logclose ;================================= ;show logのログを取得 ;================================= logopen SHLOG 0 0 sendln 'show log' pause 5 sendln '' wait '#' sendln 'exit' logclose pause 5 ;================================= ;ここでループ元に戻る ;================================= endwhile ;================================= ;FHを無効化する ;================================= fileclose FH ;================================= ;messageboxの使用 ;================================= messagebox 'Successfully Done' 'Logging' end
この画像のように、次のステップに進んでいますね。

これは10秒間だけ、<が表示されるのを待って、10秒経ったので、諦めたということになります。]]>