blog.bouzuya.net

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.