8.3.1. ループを考える
外部ファイルの中身をループするには、どこにループを挟むか考えるのが重要です。
何を実現したいかによって、ループを挟む場所を変えていく必要があります。
8.3.1.1. 前回マクロの振り返り
ここで、前回マクロを振り返ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
;================================= ;fileopenでlist.txtを開き、FHに格納 ;================================= fileopen FH 'list.txt' 0 ;================================= ;filereadlnでFHから読み出し ;LINEに格納 ;================================= filereadln FH LINE ;================================= ;LINEにIPアドレスが格納されたので、 ;LINEをIP_ADDRに代入する ;================================= IP_ADDR = LINE ;================================= ;変数格納 ;================================= PWD = 'cisco123' ;IPアドレスに必要なオプションを追加する strconcat IP_ADDR ':23 /nossh /T=1' ;================================= ;telnet接続、ログ保存ディレクトリ ;================================= connect IP_ADDR 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 'Password:' sendln PWD 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' fileclose FH end |
すでに70行にもなっているので、すべての行数を振り返ることはしません。
list.txtというIPアドレスのリストが書かれたテキストを読んで、それをIP_ADDRに代入し、そのアドレスに対してtelnetを行い、ログを取るというものです。
8.3.1.2. ループにwhileを使う
今回はループにwhileとendwhileを使っていきます。
whileについて復習しておくと、
1 |
while 値 |
の値が1でない限り、あるいは、breakしない限り、endwhileとの間をループするというものでした。
今回はwhileでマクロ全体をはさんでいくことになります。
8.3.2. whileをマクロに入れ込む
while文をマクロに組み込むにはその位置を考えることが重要です。
8.3.2.1. whileの位置を考える
whileとendwhile、fileopen関連の位置を考えるのは重要です。
なぜなら、挟み込む位置によっては、fileが不用意に閉じられてしまったり、開き直してしまったりするからです。
では、細かい途中のマクロを飛ばして、どこに入れるのが適当かを考えてみたいと思います。
そのために、以下のような省略サンプルを使って考えてみたいと思います。
1 2 3 4 |
fileopen FH 'list.txt' 0 filereadln FH LINE sendln FH fileclose FH |
例えば、以下のようにwhile、endwhileを挟むとどうなるでしょうか。
1 2 3 4 5 6 |
while 1 fileopen FH 'list.txt' 0 filereadln FH LINE sendln FH fileclose FH endwhile |
この場合、list.txtを開いて、FHを無効化する動作もループに含めてしまっているので、動きとしては以下のようになります。
ループが開始
fileopenでlist.txtを開く
FHから一行読み込んで、LINEに格納
FHを無効化する
最初に戻る
つまり、endwhileに到達した時にはすでにFHが無効化されているし、最初に戻るたびにlist.txtを開くので、ループのたびにfileopenは初期状態になってしまいます。
これでは毎回一行目しか読み込まれません。
では、以下の場合はどうなるでしょうか。
1 2 3 4 5 6 |
fileopen FH 'list.txt' 0 while 1 filereadln FH LINE sendln FH fileclose FH endwhile |
fileopenでlist.txtを開く
ループが開始
FHから一行読み込んで、LINEに格納
FHを無効化する
ループに戻る
これだと、ループの一回目でFHが無効化されてしまっているため、二回目の「FHから一行読み込んで」のときにエラーになってしまいます。
ループさせるためには、FHを無効化せずに残しておいてあげなければなりません。
よって、もっとも適当なwhile、endwhileの組み込み方は以下のようになります。
1 2 3 4 5 6 |
fileopen FH 'list.txt' 0 while 1 filereadln FH LINE sendln FH endwhile fileclose FH |
これならば、FHに格納されたlist.txtの上から1行ずつループして読んでいくことが可能です。
8.3.2.2. whileの場所
では、実際にマクロの中にwhile、endwhileを組み込んでいきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
;================================= ;fileopenでlist.txtを開き、FHに格納 ;================================= fileopen FH 'list.txt' 0 ;================================= ;whileでループを開始する ;================================= while 1 ;================================= ;filereadlnでFHから読み出し ;LINEに格納 ;================================= filereadln FH LINE ;================================= ;LINEにIPアドレスが格納されたので、 ;LINEをIP_ADDRに代入する ;================================= IP_ADDR = LINE ;================================= ;変数格納 ;================================= PWD = 'cisco123' ;IPアドレスに必要なオプションを追加する strconcat IP_ADDR ':23 /nossh /T=1' ;================================= ;telnet接続、ログ保存ディレクトリ ;================================= connect IP_ADDR 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 'Password:' sendln PWD 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 ;================================= ;ここでループ元に戻る ;================================= endwhile ;================================= ;FHを無効化する ;================================= fileclose FH end |
6-9行目でループを開始しています。
85-88行目でループの最初に戻ります。
これで、list.txtの最初から最後を読んでいくことができるようになりました。
しかし、このマクロを続けるとエラーlist.txtの最後に到達した時に、エラーになってしまいます。
それは、リストの最後まで読み込んだあとに、もう文字列がなくなってしまうので、ループを続けられなくなるからです。
次回は、ファイルの最後まで読んだ後、ループを抜けていきたいと思います。
ループを抜けるには、今度はif文を使っていく必要があります。