web-dev-qa-db-ja.com

成功したときにERRORLEVELを0にクリアするcmd.exe内部コマンドはどれですか?

Windowsバッチスクリプト内のエラーを処理するためのよくある方法は、次のようなものを使用することです。
if errorlevel 1 ...またはif %errorlevel% neq 0 ...。多くの場合、エラー処理コードでERRORLEVELを保持する必要があります。

すべての外部コマンドによって常にERRORLEVELが何らかの値に設定されると思います。そのため、エラー処理コードは、外部コマンドを実行する前に、環境変数にERRORLEVELを保持する必要があります。

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

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

ERRORLEVELをゼロにリセットする最も簡単な方法は何ですか? および Windowsバッチファイル:.bat vs .cmd? のような投稿があり、部分的な回答が得られます。しかし、私は包括的なリストを見たことがありません。

注:私はこれについて何年も興味がありました。それで、私はついにたくさんの実験を実行して、決定的な答えを思いつくことに決めました。私が見つけたものを共有するためにこのQ&Aを投稿しています。

22
dbenham

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

また注意-この回答は、内部コマンドでエラーが発生した場合のERRORLEVELの結果を文書化しようとはしません(DELとERASEに関するわずかなビットを除く)

コマンド間に違いがあるだけでなく、単一のコマンドがコマンドラインから実行されたか、_.bat_拡張子の付いたバッチスクリプト内から実行されたか、_.cmd_のバッチスクリプト内から実行されたかによって、動作が異なる場合があります。 SOMECODE)__拡張子。

次の一連のコマンドは、コンテキストに関係なく、成功時にERRORLEVELを0にクリアすることはありませんが、代わりに前のERRORLEVELを保持します。

  • ブレーク
  • CLS
  • エコー
  • ENDLOCAL
  • FOR:明らかに、DO句のコマンドでERRORLEVELが設定される場合がありますが、少なくとも1回の反復でFORが成功しても、それ自体ではERRORLEVELが0に設定されません。
  • GOTO
  • IF:明らかに、IFによって実行されるコマンドはERRORLEVELを設定する可能性がありますが、成功したIFはそれ自体でERRORLEVELを0に設定しません。
  • キー
  • 一時停止
  • POPD
  • RD
  • REM
  • RMDIR
  • シフト
  • 開始
  • 題名

次の一連のコマンドは、コンテキストに関係なく、成功すると常にERRORLEVELを0にクリアします。

  • CD
  • CHDIR
  • コピー
  • 日付
  • DEL:DELが失敗した場合でも、常にERRORLEVELをクリアします(ファイル引数なしで実行した場合を除く)
  • DIR
  • ERASE:ERASEが失敗した場合でも、常にERRORLEVELをクリアします。 (ファイル引数なしで実行する場合を除く)
  • MD
  • MKDIR
  • MKLINK
  • 移動
  • PUSHD
  • REN
  • 名前を変更
  • SETLOCAL
  • 時間
  • タイプ
  • VER
  • 確認
  • VOL

次に、コマンドラインから発行された場合、または拡張子が_.bat_のスクリプト内の場合、成功時にERRORLEVELをクリアしないコマンドがありますが、_.cmd_のスクリプトから発行された場合はERRORLEVELを0にクリアします。拡張。 https://stackoverflow.com/a/148991/101205 および https://groups.google.com/forum/#!msg/Microsoft.public.win2000.cmdprompt)を参照してください。詳細については、admin/XHeUq8oe2wk/LIEViGNmkK0J を参照してください。

  • ASSOC
  • DPATH
  • FTYPE
  • 促す
  • セットする

最後に、前のカテゴリのいずれにもうまく当てはまらない次のコマンドがあります。

  • CALL :: routineまたはバッチスクリプトがCALLされている場合、ERRORLEVELはCALLedスクリプトまたは:routineによって排他的に制御されます。ただし、コマンドに対する他のタイプの成功したCALLは、CALLedコマンドが他の方法で設定しない場合、常にERRORLEVELを0にクリアします。
    例:_call echo OK_。

  • EXIT:_/B_なしで使用すると、cmd.exeセッションが終了し、ERRORLEVELはなくなり、cmd.exeの戻りコードのみが返されます。明らかに、_EXIT /B 0_はERRORLEVELを0にクリアしますが、値のない_EXIT /B_は前のERRORLEVELを保持します。

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

25
dbenham

CALLコマンドの説明が不完全です。

CALL:CALLedコマンドでERRORLEVELが設定されていない場合は、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

出力:

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

CALLの説明は次のようになります。

  • CALL:CALLedコマンドでERRORLEVELが設定されていない場合は、ERRORLEVELをクリアします。例:call echo OKただし、呼び出されたコマンドがサブルーチンの場合は、前のERRORLEVELが保持されます。呼び出されたサブルーチンが存在しない場合は、ERRORLEVELを1に設定します。
4
Aacini