2016-01-23 6 views
21

Windowsバッチスクリプト内でエラーを頻繁に処理する方法は、
if errorlevel 1 ...またはif %errorlevel% neq 0 ...のようなものを使用することです。多くの場合、ERRORLEVELを保持するためにエラー処理コードが必要です。成功すると、cmd.exeの内部コマンドによってERRORLEVELが0にクリアされますか?

私はすべての外部コマンドが常にERRORLEVELに何らかの値を設定すると考えているので、エラー処理コードは外部コマンドを実行する前に環境変数にERRORLEVELを保持する必要があります。

しかし、内部コマンドについてはどうですか?問題は、内部コマンドによっては、成功したときにERRORLEVELを0にクリアするコマンドと、成功しなかったときにERRORLEVELを0にクリアするコマンドがあります。そして、どのコマンドが何をするのかを指定するドキュメントは見つかりません。

問題はです。内部コマンドは、成功するとERRORLEVELを0にクリアしますか?これはではなく、返されたERRORLEVELコードに関する一般的な質問ですが、厳密には成功の結果についてです。

部分回答を示すWhat is the easiest way to reset ERRORLEVEL to zero?Windows batch files: .bat vs .cmd?のような投稿があります。しかし、私は包括的なリストを見たことがありません。

注:私は長年、この好奇心てきました。だから私は最終的に一連の実験を行い、決定的な答えを出すことにしました。私はこのQ &を投稿して、私が見つけたものを共有しています。

+2

参照:http://stackoverflow.com/questions/34987885/what-are-the-errorlevel-values-set-by-internal- cmd-exe-commands/ – Aacini

答えて

21

この回答はWindows 10で実行された実験に基づいています。cmd.exeを使用する以前のWindowsバージョンとの違いはありませんが、可能です。

にも注意してください - この答えは内部コマンド(DELとERASEに関するほんの少しを除く)エラーが発生したときERRORLEVEL結果を文書化しようとしません

だけでなく、コマンドの違いはありますが、 1つのコマンドがコマンドラインから実行されたか、.batという拡張子を持つバッチスクリプト内で実行されたか、.cmd拡張子を持つバッチスクリプト内で実行されたかによって、1つのコマンドが異なる動作をすることがあります。

次の一連のコマンドは関係なく、コンテキストの、成功時に0にERRORLEVELをクリアしていないが、代わりに前ERRORLEVEL守るん:

  • BREAK
  • CLSを
  • ECHO
  • ENDLOCAL
  • FOR:明らかに、DO句のコマンドはERRORLEVELを設定できますが、少なくとも1回の反復で成功したFORは、ERRORLEVELを0に設定しません。
  • GOTO
  • IF:明らかにIFによって実行されるコマンドはERRORLEVELを設定することができますが、成功したIFはそれ自身でERRORLEVELを0に設定しません。
  • KEYS
  • PAUSE
  • POPD
  • RD
  • REM
  • RMDIR
  • SHIFT
  • START
  • TITLE

コマンドの次のセットSは関係なく、常にコンテキストの、成功時に0にERRORLEVELをクリア:

  • CD
  • CHDIR
  • COLOR
  • COPY
  • DATE
  • DEL:常にでもDEL場合、ERRORLEVELをクリアに失敗します(ファイル引数なしで実行された場合を除く)
  • DIR
  • ERASE:ERASEが失敗した場合でも、必ずERRORLEVELをクリアします。 (ファイル引数なしで実行した場合を除く)
  • MD
  • MKDIR
  • MKLINK
  • MOVE
  • PUSHD
  • REN
  • RENAME
  • SETLOCAL
  • TIME TYPE
  • VER
  • するとそこに発行された場合.bat拡張子を持つコマンドラインからまたはスクリプト内で成功時に明確ERRORLEVELをしませんこれらのコマンドがありますが、発行した場合は0にERRORLEVELをクリアしない
  • VOL

を確認拡張子が.cmdのスクリプトから詳細は、https://stackoverflow.com/a/148991/1012053およびhttps://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.admin/XHeUq8oe2wk/LIEViGNmkK0Jを参照してください。

  • ASSOC
  • DPATH
  • FTYPE
  • PATH
  • PROMPT
  • SET

最後に、前のカテゴリのいずれにもきちんとフィットしていないこれらのコマンドがあります:

  • CALL:ルーチンまたはバッチスクリプトがCALLされた場合、ERRORLEVELはCALLされたスクリプトまたは:ルーチンによって排他的に制御されます。しかし、他のタイプのコマンドへの成功したCALLは、CALLされたコマンドがそれ以外の方法でそれを設定しなければ、常にERRORLEVELを0にクリアします。
    例:call echo OK

  • EXIT:/Bなしで使用すると、cmd.exeセッションは終了し、それ以上のエラーはなく、cmd.exeのリターンコードだけがあります。明らかにEXIT /B 0はERRORLEVELを0にクリアするが、値を持たないEXIT /Bは以前のERRORLEVELを保持する。

私が逃した文書化されていないコマンドがない限り、すべての内部コマンドを考慮していると思います。

+1

'KEYS'が欠けています:)(エラーレベルをクリアしません) – npocmaka

+0

@npocmaka - ありがとう、リストに追加しました – dbenham

+0

...ちょっとメモ:' rem' Windows NT 4.0では 'ErrorLevel'を0にリセットします。私が覚えている限り、これはWindows XP以降に修正されています。 – aschipfl

4

CALLコマンドのあなたの記述が不完全である:

CALL:というコマンドがそうでなければ、それを設定しない場合はERRORLEVELをクリアします。 例:call echo OK

チェックこの小さな例を:

@echo off 

call :setTwo 
echo Set two: %errorlevel% 

call :preserve 
echo Preserve: %errorlevel% 

call echo Reset 
echo Reset: %errorlevel% 

call :subNotExists 2> NUL 
echo Sub not exist: %errorlevel% 

goto :EOF 

:setTwo 
exit /B 2 

:preserve 
echo Preserve 
exit /B 

は出力:

  • CALL::というコマンドがない場合はERRORLEVELをクリアし

    Set two: 2 
    Preserve 
    Preserve: 2 
    Reset 
    Reset: 0 
    Sub not exist: 1 
    

    CALL説明は、このような何かを言う必要がありますそれ以外の場合は設定しないでください。例:call echo OKですが、呼び出されたコマンドがサブルーチンであれば、それは以前のERRORLEVELを保持します。呼び出されたサブルーチンが存在しない場合、ERRORLEVELは1に設定されます。

+1

質問は***成功した***内部コマンドの結果にすぎないとすれば、私の答えはこの答えに反しません。失敗したコマンド結果に関する情報を選択的に追加することを選択しました。有用な情報ですが、質問には答えません。私は、内部コマンドエラー処理に関する一般的な質問をすることを考えましたが、それは広すぎて答えが難しいと判断しました。 (私はいつか包括的な論文を見たいですが!)私はまた、選択的に私の答えにエラーの結果を含めることを考えたが、それをきれいに保つことを選んだ - 厳密には成功の結果について。 – dbenham

+1

これを確認してください - 私はDELとERASEの記述で私の答えにちょっとしたエラーの結果を聞かせました;-) – dbenham

+0

まあ、「ERRORLEVEL = 1はサブルーチンが存在しないとき」を除いて、「呼び出されたコマンドが以前のERRORLEVEL "部分を保存するサブルーチンは_successful_結果を参照します。とにかく、この話題は一般的に内部コマンドによって設定された値について話すべきだと私は本当に思っています。私はこの部分があまりにも広すぎないと思うのは、特定のコマンドがそのような条件の非常に簡単な説明だけでエラー状態のERRORLEVELを1に設定しているということだけです。 IMO ERRORLEVEL = 0でない部分は、ERRORLEVEL = 0部分の説明から除外することはできません。 – Aacini

関連する問題