バッチファイルのテンプレート


テンプレート

ありがちなbatファイルのテンプレートを作成した。

template.bat

template.bat
@echo off
setlocal enabledelayedexpansion

:main
    pushd %~dp0

    rem set arguments
    set arg1=%1
    set arg2=%2

    rem check arguments
    call :check_arg1 %arg1%
    call :check_arg2 %arg2%

    rem import ini files
    set ini=test.ini test2.ini
    for %%i in (%ini%) do call :import_ini %%i

    rem body
    echo arg1=%arg1%
    echo arg2=%arg2%
    echo temp=%temp%
    echo temp2=%temp2%

    popd
exit /b

:check_arg1
    if "%1" == "a" (
        rem something to do
    ) else if "%1" == "b" (
        rem something to do
    ) else (
        echo ERROR : wrong argument arg1=%arg1%
        exit
    )
exit /b

:check_arg2
    if "%1" == "a" (
        rem something to do
    ) else if "%1" == "b" (
        rem something to do
    ) else (
        echo ERROR : wrong argument arg2=%arg2%
        exit
    )
exit /b

:import_ini
    for /f "tokens=1,2* delims==" %%i in (%1) do (
        if not %%i == # (
            set %%i=%%j
        )
    )
exit /b

endlocal

解説

コマンド実行非表示の設定

デフォルトだと実行したコマンドまでDOS窓に表示されてうざい。echo offで非表示にできる。このとき、文頭に@をつけないとecho off自体が表示されてうざい。

@echo off

遅延環境変数展開の設定

デフォルトだとforループ内で変数が使えなくて悲しい。遅延環境変数展開enabledelayedexpansionを設定すると、変数を利用できる。この際変数は%val%ではなく!val!と記述しなければならない。めんどい。

setlocal enabledelayedexpansion

(中略)

endlocal

カレントディレクトリ移動

%~dp0で自ファイルの絶対パスを取得できる。pushdでディレクトリを移動する。pushdcdとは異なり、移動先のディレクトリをネットワークドライブに設定してから移動するので、\\xxx.xxx.xxx.xxx\pathのようなディレクトリでも問題なく移動できる。

pushd %~dp0

(中略)

popd

引数取得

引数は順番に%1%2と記述すれば取得できる。

set arg1=%1
set arg2=%2

サブルーチン化

タグ名:check_arg1exit /bを使えばサブルーチンを定義できる。また、引数も渡せる。引数は順番に%1%2と記述すれば取得できる。裏ワザっぽいけど。
また、サブルーチンはcall :タグ 引数と記述して呼び出す。

call :check_arg1 %arg1%

(中略)

:check_arg1
    if "%1" == "a" (

(中略)

exit /b

iniファイル読込

謎に充実した機能を持つfor文を駆使すれば、iniファイルも読み込める。for /f "tokens=1,2* delims==" %%i in (%1)は、ファイル内から一行読み出し(/f)しつつ、各行を=で2分割する("tokens=1,2* delims==")ということ。

set ini=test.ini test2.ini
for %%i in (%ini%) do call :import_ini %%i

(中略)

:import_ini
    for /f "tokens=1,2* delims==" %%i in (%1) do (
        if not %%i == # (
            set %%i=%%j
        )
    )
exit /b

iniファイルはこんな感じで書ける。

test.ini
# comment
param=value