高速 ping
IPアドレス調査高速化
DHCPで割り当てられた他装置のIPアドレスを高速に調べたい。
非サーバ管理者を前提とする。
方法
シーケンシャルping
for文でping -c 1 - w 0.5 などを繰り返す。
多重ping
pingを多重実行し、結果を刈り取る。
前半でpingを非同期実行し、pidとipアドレスを配列に保管する。
後半で配列からpidとipアドレスを取り出し、pid毎にping結果を受け取る。
下記ではpingを254多重で実行する。
#!/bin/sh base=192.168.0 from=1 to=254 list=`seq $from $to` function oneping(){ ad=$1 ping -c 1 -w 0.5 $ad 2>&1 >/dev/null } pids=() ipas=() for ix in $list ; do ipa="${base}.$ix" oneping ${ipa} & pids+=($!) ipas+=($ipa) done cnt=0 for ix in $list ; do pid=$(pids[$cnt]) ipa=$(ipas[$cnt]) wait $pid if [ $? -eq 0 ]; then # ping success echo $ipa fi cnt=$(( $cnt + 1 )) done
ポイント
- sh関数をbg実行できる。
- pids, ipas配列を使う。
- waitの戻り値 $? を使う。
- 最後に実行したプロセスのpid が$!
- pingの待ち時間を -w 秒 で指定。
- pingが成功したip addressのみを表示する。
- 関数 oneping の戻り値はreturnを省略しているため、最後に実行したpingの終了ステータスになる。
- 関数の戻り値は、0-255 であり、returnで指定するか、指定しない場合は最後のコマンドの終了ステータスとなる。
- 関数内のローカル変数は、localで指定する。(bashの場合)
今後
今後の発展としては、実行結果をDBに登録し、前回の結果と比較し、差分を抽出する。
選択肢は、
- DBへの登録間隔。
- 履歴を保管する方法。保管する世代数。保管方法、保管単位(アドレス単位、調査実施単位、差分のみ等)
- 差分の表示方法
差分の保管方法1
調査データは下記項目。
調査時刻、(アドレス、ping結果) x N
Table 1: 調査ID, 時刻 Table 2: 結果ID, 調査ID,アドレス,ping結果
差分: 調査id-a,bの比較
アドレス毎に、ping結果が異なる物を抽出する。
差分の保管方法2
Table 1 案1と同じ
Table 2 結果id,調査id,アドレス
Table 2に登録されるのは、pingが成功したもののみ。
差分: 前回調査で存在しなかったものが追加されたアドレス。前回調査に存在したが、今回存在しないものが消えたもの。
テーブルを2回引くか、joinして抽出する。
案2だと、ping失敗レコードが不要な為、DBサイズが案1より小さい。
dhcpで新規登録されたアドレスを探す目的であり、案2で増えたアドレスを表示するのが、簡単。
差分の保管方法3
アドレスをキーにする案。
アドレス, 前回結果
新規調査時、前回と結果が異なればテーブルを更新し、差分を表示。
履歴が一世代しか取れないが単純。
履歴が必要なら、同じ形式のテーブルを世代数分持つ方法もある。
その他
簡素化のため、出力ファイルをgit登録。 git dif により差分確認。
参考
https://bash.cyberciti.biz/guide/Putting_functions_in_background