バッチファイル内であるアプリケーションの戻り値(返り値)を取得したい場合は
そのアプリケーションを実行した後%ERRORLEVEL%
で取得できる
仮に 何かファイルを渡して、処理が成功すれば0
が返り、失敗すれば1
が返るhoge.exe
というのがあったとして
call hoge.exe piyo.txt
if %ERRORLEVEL% == 1 @echo ダメです。
という感じで条件分岐だって可能だし
さてさてこれを利用して大量の処理をしたくなったとき(ってかバッチ処理ってそんなもの)
for %%f in (*.txt) do (
call hoge.exe %%f
if %ERRORLEVEL% == 1 @echo %%f:ダメです。>> log.log
)
的なことをやろうとして、思ったような結果が得られず、(この場合はERRORLEVEL
がいつまでたっても0のまま)えらい難儀している人はたくさんいると思う。
setlocal
(コマンド文)
endlocal
で挟んでやっても・・・・どうにもうまくいきません。
どうやらこれはバッチファイルの中にインタプリタ(?)する過程で、for do
ループがあると、そのブロック内は一度に評価される。
そのため「%ERRORLEVEL%
ほにゃらら」 は、その時点での値がそのまま埋め込まれて実行されるからだとか・・・(少々間違った解釈かも知れんが、とにかくこのままでは動的な変数のごとく使えないってことだ)
これを「環境変数の即時展開」というものらしい
じゃあ、環境変数を動的に扱いたい場合どうすればいいのか
その解決策は「環境変数の遅延展開」と呼ばれるもの
つまりsetlocal
にenabledelayedexpansion
のオプションをつけてやる
長いですね
遅延:delayed
展開:expansion
有効:enable
具体的には
setlocal enabledelayedexpansion
から始まってendlocal
までの間はこれが有効となる。
さらにこの中では環境変数の呼び出し方を%
ではなく!
で挟むようにしてやればOK
使用例としては
setlocal enabledelayedexpansion
for %%f in (*.txt) do (
call hoge.exe %%f
if !ERRORLEVEL! == 1 @echo %%f:ダメです。>> log.log
if !ERRORLEVEL! == 0 @echo %%f:OKです。>> log.log
)
endlocal
初心者(中級者でも)が大ハマリするパターンだろう、
「どう考えても動くバッチに見えて仕方がないのに何で思うように動かないのか・・・・・・」
一度は苦労する点であることには間違いない、
別ブログに掲載していた記事をQiitaに掲載