プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
Windows、バッチファイルでエラーレベルが取れない。(遅延環境変数の展開)
バッチファイルのエラー処理で微妙にハマりました。
ファイルをコピーして、その結果を%errorlevel%で判定していたのですがね。

SETLOCAL

@COPY C:\A.txt Z:\B.txt

IF %ERRORLEVEL% NEQ 0 (
    ECHO エラー。
    EXIT
)

ENDLOCAL


これはOK。
次に以下のテキストファイルを用意してループさせてコピーした所・・
コピーできなくてもエラーレベルが変わらない(#゚д゚)

◆テキストファイルの中身(text.txt)
 C:\B.txt
 C:\C.txt
 Z:\D.txt


◆コード
SETLOCAL

FOR /F "delims=" %%a IN (C:\text.txt) DO (

    @COPY C:\A.txt %%a

    IF %ERRORLEVEL% NEQ 0 (
        ECHO エラー。
    )
)

ENDLOCAL


なんでだぁ<( ̄◇ ̄;)>
色々調べた所、こんな感じにしたら動きましたφ(--)

SETLOCAL enabledelayedexpansion
FOR /F "delims=" %%a IN (C:\text.txt) DO (

    @COPY C:\A.txt %%a

    IF
!ERRORLEVEL! NEQ 0 (
        ECHO エラー。
    )
)

ENDLOCAL


SETLOCALにenabledelayedexpansionを指定して
変数へのアクセスをパーセント(%)からエクスクラメーションマーク(!)へ変更。
取りあえずFOR文の中とかでエラーレベル判定行っている場合は
こんなんするのが簡単な解決方法みたいです。

理屈が気になる方は「遅延環境変数の展開」でgoogle先生に訊いて下さい。
ざっくり書くと、パーセント(%)アクセスは構文解析時に環境変数を展開、
エクスクラメーションマーク(!)アクセスは実行直前に環境変数を展開らしいです。


setlocal enabledelayedexpansion

set aaa=bbb

IF 0 (

set aaa=ccc
echo %aaa%
echo !aaa!

)
pause

endlocal


とかやってみるとイメージ出来ますかね。
IF文の実行前に%aaa%は展開されちゃっているので、

setlocal enabledelayedexpansion

set aaa=bbb

IF 0 (

set aaa=ccc
echo
bbb
echo !aaa!

)
pause

endlocal


と同じ事になるのだと思います。
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:コマンド/バッチ  thema:プログラミング - genre:コンピュータ  Posted by ササキマコト 

  関連記事