FOR IN() 句内のコマンドは、まったく新しい CMD.EXE セッションで実行されるため、コマンドが設定する可能性のある ERRORLEVEL または環境変数に直接アクセスすることはできません。
通常、最善かつ最も簡単な解決策は、一時ファイルを使用することです。
yourCommand >output.txt
set exit_code=%errorlevel%
for /f "delims=" %%i in (output.txt) do processOutput
del output.txt
ただし、一時ファイルは使用できないと述べています。
唯一のオプションは、IN() 句内で ERRORLEVEL をエコーし、DO 句内で ERRORLEVEL を解析することです。%ERRORLEVEL% は解析時に展開され、IN() 句全体が一度に解析されるため、%ERRORLEVEL% は常に 0 になるため、ERRORLEVEL のエコーは少し注意が必要です。
IN() 句のコマンドは、バッチ コンテキストではなく、コマンド ライン コンテキストで実行されます。新しい CMD.EXE セッションは、現在の遅延拡張状態を継承しません。デフォルトでは、遅延拡張が無効になっています。最も簡単な解決策は、適切にエスケープされた CALL を使用して%ERRORLEVEL%
、コマンドが実行されるまで展開を遅らせることです。コマンド コンテキストをエスケープするためにキャレットが追加されます。次に、パーセントとキャレットを 2 倍にして、親バッチ - をエスケープします%%^^ERRORLEVEL%%
。
DO 句で ERRORLEVEL と通常の出力を区別できるように、ERRORLEVEL メッセージを一意にする必要があります。
@echo off
setlocal enableDelayedExpansion
for /f "delims=" %%A in ('dir DoesNotExist^&call echo ::ERROR::%%^^ERRORLEVEL%%') do (
set "ln=%%A"
if "!ln:~0,9!" equ "::ERROR::" (
set "EXIT_CODE=!LN:~9!"
) else (
REM normal output - do whatever
echo %%A
)
)
echo EXIT_CODE=%EXIT_CODE%
上記の出力例を次に示します。
C:\test>test.bat
File Not Found
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
EXIT_CODE=1