昔も今も変わらぬバッチファイルのお作法

バッチファイルはその名のとおり、Windowsのシェル(コマンドプロンプト)で実行させたい処理を、まとめて呼び出して走らせるための、拡張子がbatのテキストファイルで、いにしえのDosの時代から存在しました。

新卒入社したシステム会社で、Windows NT上で複数のフォルダをまるごとコピー(xcopy)する処理を書いたのがバッチファイル初体験でしたが、学生時代のパソコン(死語?)の授業で寝ていた僕は、とにかく特殊記号(@, % <など)アレルギーで、意味を説明されても慣れるのにずいぶん時間がかかりました。

プログラムの自動更新バッチファイル

業務システム運用上でのバッチファイルの定番として、クライアントモジュールを起動する際に、サーバー上の最新版のバージョンをチェックして、新しければ自動アップデートする、というのがありまして、これには繰り返し(for)と条件分岐(if)と遅延環境変数の展開(enabledelayedexpansion)という、難しいシェルコマンドの作法が含まれています。

  • 1行目:@で自コマンドを表示しない。echo offで以降のコマンドも表示しない。
  • 2行目:バッチファイルが実行されているディレクトリ(カレントディレクトリ)を環境変数%CD%から取得し変数にセット。
  • 3行目:プログラムが置かれたサーバーのディレクトリのパスを変数にセット。
  • 5行目:Pingコマンド 試行1回、タイムアウト1秒
  • 6行目:環境変数errorlevelの値が1ならerrorルーチンに飛ぶ
  • 9行目:for (オプション) %%アルファベット1文字 in (ループ処理の対象) do コマンド
    in (%SVRDIR%\setting.ini):プログラムが置かれたサーバーのディレクトリにあるsetting.iniの中が対象
    /f:テキストファイルからトークン(文字列の最小単位で通常はタブ区切り文字)を取り出して代入
    “tokens=1,2 delims==” %%a:イコール(”=”)区切りのトークンの1番目を変数%%a、2番目を変数%%bに取得
  • 10行目:変数%%aの値が”version”であれば、変数%%bの値を変数versionに代入
  • 13行目:for (オプション) %%アルファベット1文字 in (ループ処理の対象) do コマンド
    in (ver.ini):カレントディレクトリにあるver.iniの中が対象
    /f:テキストファイルからトークン(文字列の最小単位で通常はタブ区切り文字)を取り出して代入
    “tokens=1,2 delims==” %%a:イコール(”=”)区切りのトークンの1番目を変数%%a、2番目を変数%%bに取得
  • 14行目:変数%%aの値が”ver”であれば、変数%%bの値を変数verに代入
  • 16行目:VerがVersionより小さければupdルーチンに飛ぶ
  • 17行目:更新成功時にはprocessルーチンに飛ぶ
  • 18行目:バッチファイルの最後に移動する。

サーバー上にあるsetting.iniファイル

カレントディレクトリにあるver.iniファイル

  • 23行目:サーバーのディレクトリをカレントディレクトリにまるまるコピー
    /sオプション:ファイルが存在する場合のみディレクトリごとコピー
    /yオプション:同名のファイルが存在する場合、上書きの確認を行わない
  • 24行目:定義した変数のローカル化(setlocal~endlocalの外に影響しない)
    enabledelayedexpansionオプション:実行中に変数の値が変化
  • 25行目:for (オプション) %%アルファベット1文字 in (ループ処理の対象) do コマンド
    in (ver.ini):カレントディレクトリにあるver.iniの中が対象
    /f:テキストファイルからトークン(文字列の最小単位で通常はタブ区切り文字)を取り出して代入
    “tokens=*” %%a:すべての文字列を変数%%aに取得
  • 27行目:変数varに”var=変数version”をセット
  • 28行目:変数verをoutput.iniファイルに書き出す。
  • 30行目:ver.iniを削除
  • 31行目:output.iniをver.iniにリネーム
  • 40行目:AccountPROのリンクをAccountPROというタイトルで開く
    startコマンドの第1引数はアプリケーションのタイトルを設定する文字列
  • 42行目:バッチファイルを途中で終了させる。
  • 43行目:バッチファイルの最後に移動する。
  • 49行目:「Please press any key to continue…」を表示させ何かしらのキー入力があるまで動作を停止。

コマンドの書き方あれこれ

Unixのカーネル(核)を操作するシェル(貝)コマンドはcygwinのようなターミナル(端末)から入力しますが、Windowsのカーネルを操作するコマンドプロンプト(cmd.exe)はコンソール(ターミナルではない)から入力します。

環境変数

Windowsのシステム環境変数の代表格Pathに、コマンドを実行するプログラムのあるディレクトリを設定することで、コマンドプロンプトからフルパスを入れずコマンドのみで実行できますが、これらシステム環境変数はWindows環境で共通なので、自分のPCで作成したバッチファイルを他人のPCで実行することができます。

一方で環境変数はユーザー自身が独自に定義することも可能で、「SET」コマンドで定義して「%環境変数%」でバッチファイル中で参照することができます。

日付と時間の取得

バッチファイルから取得する日付のフォーマットは、コントロールパネルのRegion and language(地域と言語)から設定されますが、日本式のyyyy/MM/ddと英語のM/d/yyyyとでは方法が異なります。

日本式(yyyy/MM/dd)の場合

英語式(M/d/yyyy)の場合

pingのエラーレベル

pingコマンドはオプションと引数のセットで指定しますが、「-n 1」で試行回数1回、「-w 1000」でタイムアウト時間を1000ミリ秒(1秒)に指定しますが、結果に応じて環境変数errorlevelに以下の値を返します。

  • ホストが見つからない:1
  • 応答なし:1
  • 応答あり:0
  • 経路なし:0

ルーターを経由しない社内LAN上のサーバーであれば「経路なし」はありえないので、errorlevelが0(応答あり)か1(応答なし)で判断できます。

エスケープシーケンス

環境変数に特殊記号を代入する場合に、エスケープ文字(^)を付ける必要があり、例えばユーザー環境変数LOGOに「&TOKYO」という文字列を入れる場合は、SET LOGO=^&TOKYO となります。

こんな投稿も読まれています