かねてから「毎回めんどくさい」と思ってた事を自動実行するバッチファイルを書きました。洗練されてませんが、自分メモとして公開します。
何ができるバッチ?
- 実行する度に、ターゲットホストのIPアドレスをチェックします。
- IPアドレスが変更された場合、旧いスタティックルートを消して新しいスタティックルートを追加します。
自分の環境「WiMAXとDSLを同時に使って対障害な回線二重化を行う | 徒労日記」にて、自宅IPアドレスが変わる度にスタティックルートを変更する為のバッチファイルです。外に出る経路が2回線あって、そのうち希望の相手だけは決まった経路にしたいと。
自分と同じ環境の人はまれでしょうが、たとえば「インターネットはワイヤレス、ファイル共有はローカル接続だけど、特定のホストだけ希望のインターフェイスを通したい」って場合も使えるかと。最後の:ROUTEADDセクションにあるroute文をIF付きに直せばいけます。
動作要件
- Windows7で動作(XPなどは一部コマンドが実行できないかも)
- 外部ルーツを使用しません
- 相手はDDNS等でFQDNが自動登録される必要があり
- 何もルートを追加していない状態で使用開始を想定
- NOW_TARGETIPのファイルを消すと無条件ルート追加します
ファイル本体
@echo off SET TARGET_HOST=hogehoge.hoge.com SET FILETEMP=W:\TEMP SET NOW_TARGETIP=D:\now_targetip.txt SET NEW_TARGETIP=W:\new_targetip.txt SET TARGET_GATEWAY=192.168.1.xxx REM TargetIPを格納 ping -n 1 %TARGET_HOST% > %FILETEMP%\target.txt setx TARGET_IP -f %FILETEMP%\target.txt -a 2,0 >> NULL echo %TARGET_IP% > %NEW_TARGETIP% REM 初期処理 if not exist %NOW_TARGETIP% (echo 127.0.0.1 > %NOW_TARGETIP% && GOTO ROUTEADD) REM 比較 fc %NOW_TARGETIP% %NEW_TARGETIP% >> NULL if errorlevel 1 goto ROUTEDEL if errorlevel 0 goto END :ROUTEDEL REM 旧TargetIPをroute削除 for /f "delims=" %%a IN ('type %NOW_TARGETIP%') do set DELETEIP=%%a route delete %DELETEIP% >> NULL :ROUTEADD REM 新TargetIPでルート追加 route -p add %TARGET_IP% MASK 255.255.255.255 %TARGET_GATEWAY% >> NULL echo %TARGET_IP% > %NOW_TARGETIP% :END
SET TARGET_HOST= は設定したい相手ホスト(FQDN)
SET FILETEMP= はゴミファイルを書いていいテンポラリフォルダ
SET NOW_TARGETIP= は設定済みの相手IPを保持するファイル
SET NEW_TARGETIP= はチェックした相手IPを書くファイル(テンポラリ内でOK)
SET TARGET_GATEWAY= はルートにしたいゲートウェイ
解説メモ
setx
ファイルの中から特定部分だけを環境変数へ格納できる。一度-xオプションをつけて実行する事で、-fで指定したファイルが分解され、座標が表示される。その座標を-aにつけて指定する。
fc
ファイル比較。比較結果は長くなるが、差異があった場合は%ERRORLEVEL%に1,無かった場合は0が入る
for /f “delims=” %%a IN (‘type filename‘) do …
ファイルの内容を読み込んで%%aに格納できる。%%aは環境変数とは別物。”delims=”は区切り文字を指定するが、無い場合は半角スペース。tokens=とセットで使うと、デリミタ(delims)で区切られた何個目の単語(tokens)を抜き出すか指定できる。
2012/10/24 追記
調べてみるとsetxコマンドは値を格納した後、次に開いたコマンドプロンプトウィンドウ(CMDセッション)からは初めて値が有効になるそうです。
今回のバッチファイルでいえば、相手のIPが変わっても1回目は検出できず、2回目の実行でテーブルが書き換えられます。レスポンスを気にされる方は更新ペースを短くするか、2回セットで実行するようにすれば解決できます。