2012-10-28 WindowsバッチファイルのTips
予告どおりWindowsバッチについて書く。基礎的な部分から書こうかとも思ったが、すでに多くのサイトで書かれているので、巨人の方に乗る意味で、そちらをまず紹介して、その補足だけしようと思う。
最初に『Windowsコマンドプロンプト基礎文法最速マスター』を読む。よく網羅されている。
何点か補足しておく。
標準エラー出力にファイルを使う
標準エラー出力にファイルを使うことができる。シェルスクリプトなどに慣れていれば当たり前の知識だけれど、Windowsバッチファイルでも標準出力だけでなく標準エラー出力も制御できる。書きかたも同じ2>
のように記載するだけだ。
script.bat 1>stdout.txt
script.bat 2>stderr.txt
ほかにも標準エラー出力にファイル記述子1の出力先を使う、2>&1
も使える。
script.bat 1>outorerr.txt 2>&1
出力を捨てる
出力を捨てることができる。シェルスクリプトにおける/dev/null
である。Windowsバッチファイルではnul
と書く。null
ではなくnul
である。null
とするとnull
という名前のファイルが作成されてしまう。
script.bat 1> nul
ERRORLEVELの判定
変数ERRORLEVELには、直前のコマンドのリターンコードが格納されることは記載されているけれど、その判定は意外と難しい。
%ERRORLEVEL%
と記載した場合には、その展開タイミングによっては想定どおりに動かないことがある。IF
コマンドにERRORLEVEL
という条件があるのはそのためだ。
IF ERRORLEVEL 0 ...
これでERRORLEVELが0「以上」の場合に真となる。負の数の場合にエラー(真)としたいなら、次のようになる。
IF NOT ERRORLEVEL 0
変数の展開
引数以外の変数について変数展開をするにはFOR
コマンドを使うことができる。
REM 相対パスで指定された変数DIRを完全修飾名に展開する例
SET DIR=Documents
FOR /F "delims=" %%I IN ("%DIR%") DO ECHO %%~fI
上記はバッチファイル内での記載である(変数の展開タイミングを変えるため「%」を重ねている)。また空白を含むパスの展開のために"delims="
を指定して区切り文字をなくしている。
ファイルやディレクトリに対しての繰り返し
元記事ではIF GOTO
によるループやFOR
コマンドによる簡単なループが紹介されているが、よくあるのはファイルやディレクトリに対するループである。このループもFOR
コマンドが便利である。
REM ディレクトリに対するループ
FOR /F "delims=" %%I IN ('DIR /B /AD') DO ECHO %%I
REM ファイルに対するループ
FOR /F "delims=" %%I IN ('DIR /B /A-D') DO ECHO %%I
DIR
コマンドの出力をパーズしているだけである。ECHO
部分を変更すると良い。
setlocalで環境の破壊を防ぐ
環境を壊さないためにsetlocal
を使っておく。
setlocal
を使うと変数の有効範囲を設定できる。外部の環境を設定するためのバッチや、複数バッチファイルに共通の設定を書いている場合を除いては、setlocal
しておくことをおすすめする。
こんなとこかな。いろいろ忘れてそうだけど。あー疲れた。
60 min.