コマンドの終了ステータスが取れない
errorlevel
コマンドプロンプトからコマンドを実行すると、成功したか失敗したかが数値で返ってくる。
その値は errorlevel で見ることができる。
C:\> dir ... C:\> echo %errorlevel% 0 C:\> dirr 'dirr' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 C:\> echo %errorlevel% 9009 C:\>dir not.found ファイルが見つかりません C:\> echo %errorlevel% 1
errorlevel に代入してはいけない
この errorlevel は変数ではない。
間違って errorlevel に値を代入してしまうと、コマンド終了ステータスを見ることができなくなる。
C:\> set errorlevel=0 C:\> echo %errorlevel% 0 C:\> dirr 'dirr' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 C:\> echo %errorlevel% 0
errorlevel に値を代入すると、変数の errorlevel ができてしまって、本来の errorlevel にアクセスできないらしい。
errorlevel はエラーの重要度
DOS 用のコマンドを作るとき、
- ファイルがないときは exit(2)
- アクセス権がなければ exit(5)
- etc.
などと設計するのは間違い。
コマンドの終了ステータスはエラーの種類ではなく、エラーの重要度。
C:\> dirr 'dirr' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 C:\> if errorlevel 3 echo NG NG C:\> dir not.found ファイルが見つかりません C:\> if errorlevel 3 echo NG
if errorlevel を使うと、指定した重要度以上のエラーを検知することができる。
if %errorlevel% == 3 とは違う。
if errorlevel は変数の errorlevel は見ないので、間違って値を代入しても正しく動く。
errorlevel が変化しない
ここからが本題。
コマンドを実行しても errorlevel が変化しなくてハマった。
VisualStudio のデバッグウィンドウには
「プログラム '……' はコード 100 (0x64) で終了しました。」
と表示されているのに、コマンドプロンプトから実行すると errorlevel が 0 のまま。
Cygwin の bash から実行しても $? は 100 になるのに。なぜ?
ググッてググッてググりまくった結果、
コマンドプロンプトから実行してもセットされないのに、バッチファイルから実行したらセットされる。
と怒ってる人がいた。
まさかと思ってやってみた。
C:\> type wrap.bat @echo off %* echo %errorlevel% C:\> wrap foo.exe 100
できた。なぜ??
原因は分からないが、そういうもんらしい。
わざわざバッチファイルを作らなくても、これでイケるみたい。
C:\> cmd /C foo C:\> echo %errorlevel% 100