web-dev-qa-db-ja.com

内部のcmd.exeコマンドによって設定されるERRORLEVEL値は何ですか?

ERRORLEVELは、一連の条件に応じて変更が終了したときにほとんどのcmd.exeコマンドによって返される値です。したがって、コマンドが返す値を知ることは、より優れたバッチファイルの作成に役立つ貴重な情報です。すべての外部.exeプログラムは終了時にERRORLEVELを変更します(これは ExitProcessTerminateProcess Win-32 API関数の両方の固有のメカニズムです)。通常、このような値は文書化されますが、 internalcmd.exeコマンドによって返される値は、他の場所では完全に文書化されていません。

部分的なERRORLEVEL値を持つテーブルは この質問 に表示されますが、ERRORLEVEL = 0を「成功時」に設定する内部コマンドの場合のみです。 「成功しなかったコマンド」によって返される値も含めるために、そのような質問のOPを変更することを提案しましたが、彼は拒否し、私自身の質問/回答を投稿するように私を招待しました。ゼロ以外のERRORLEVELは、notは必ずコマンドが失敗したことを意味することに注意してください!内部コマンド(SET /Pなど)など、エラーなしで終了し、異なる「終了ステータス」を示すゼロより大きい値を返すコマンドがいくつかあります。

Batch .batファイルの組み込みのcmd.exeコマンドをより有効に使用するには、返されるERRORLEVEL値と、この管理に含まれるメカニズムを知る必要があります。そこで質問は、internal cmd.exe commandsERRORLEVELをany value(ゼロを含む)に設定することです)?

21
Aacini

この回答では、すべての内部cmd.exeコマンドによって返されるERRORLEVEL値が説明されています。これらは、値の変更方法ごとにグループ化され、クイックリファレンステーブルとして表示されます。これを組み立てるために他の同様の表を検討しましたが、Windows 8.1コンピューターで実行されたテストを介して欠損値を埋めました。これらのテーブルを完全かつ正確に作成するために最善を尽くしましたが、ここで報告されているすべての値をテストしていなかったため、微妙な矛盾がある可能性があります。

表1-以前のERRORLEVEL値を変更しないコマンド

BREAK
ECHO
ENDLOCAL
FOR      Not change the ERRORLEVEL by itself. See "Exit Code" below.
IF       Not change the ERRORLEVEL by itself.
PAUSE
RD       Not change the ERRORLEVEL on errors, but the "Exit Code". See below.
REM
RMDIR    Same as RD.
SET      Plain SET command (no arguments). See "Table 3" below.
TITLE

表2-結果に応じてERRORLEVELを0または1に設定するコマンド

Command │ Set ERRORLEVEL = 0 when       │ Set ERRORLEVEL = 1 when
────────┼───────────────────────────────┼─────────────────────────────────────────────────────────────
CD      │Current directory was changed. │Directory not exists or is not accessible.
CHDIR   │Same as CD.                    │
COLOR   │Color was changed.             │Background and foreground colors are the same.
COPY    │File(s) was processed.         │File not found or bad parameters given.
DATE    │Date was changed or not given. │User has no admin privileges.
DEL     │Almost always, excepting when: │Bad or no parameters given.
DIR     │Same as COPY.                  │
ERASE   │Same as DEL.                   │
MD      │Directory was created.         │Directory could not be created.
MKDIR   │Same as MD.                    │
MKLINK  │Link was created.              │Link could not be created or bad parameters given.
MOVE    │File(s) was moved/renamed.     │File not found, could not be moved/renamed or bad parameters.
PUSHD   │Same as CD.                    │+ Bad switch given.
REN     │Same as MOVE.                  │
RENAME  │Same as MOVE.                  │
SETLOCAL│New environment was created.   │Bad parameters given.
TIME    │Time was changed or not given. │User has no admin privileges.
TYPE    │Same as COPY.                  │
VERIFY  │Right or no parameters given.  │Bad parameters given.
VOL     │Volume label was displayed.    │Drive not found or bad parameters given.

表3-エラー時にERRORLEVELを設定するコマンド。それ以外の場合は、変更しません

Command      │E│ Set ERRORLEVEL to = when
─────────────┼─┼────────────────────────────────────────────────────────────────────────
ASSOC        │*│1 = Extension associations could not be changed.
CLS          │ │1 = Bad switch given.
DPATH        │*│1 = Data path could not be established.
FTYPE        │*│1 = File type associations could not be changed.
GOTO label   │ │1 = Label not exist *in a subroutine* (equivalent to: EXIT /B 1).
KEYS         │ │1 = Bad switch given.
PATH         │*│1 = Path could not be changed.
POPD         │ │1 = Bad switch given.
Prompt       |*│1 = Prompt could not be changed.
SET var      │*│1 = No variable with such name exists.
SET var=value│*│1 = Variable name start with "/" not enclosed in quotes.
SET /P       │*│1 = Read an empty line or at end of file.
SET /A       │*│1073750988 = Unbalanced parentheses, 1073750989 = Missing operand, 
             │ │1073750990 = Syntax error, 1073750991 = Invalid number,
             │ │1073750992 = Number larger than 32-bits, 1073750993 = Division by zero.
SHIFT        │ │1 = Bad switch given.

表3の「E」列は、対応するドキュメントで説明されているように、「拡張」ステータスに応じて動作を変更するコマンドを示しています。拡張機能が有効(デフォルト)であり、これらのコマンドが.CMDの代わりに.BAT拡張子を持つファイルに配置されている場合、これらのコマンドはエラーなしで終了するとき、つまり表3に記載されている条件は、notです。

表4-特殊なケース

CALL Table1     │If the called command is anyone of Table 1 (excepting FOR and IF): set ERRORLEVEL = 0.
CALL subroutine │If the subroutine is called, not change prior ERRORLEVEL value;
                │otherwise (subroutine not exists): set ERRORLEVEL = 1.
EXIT /B, EXIT   │Not change prior ERRORLEVEL value.
EXIT /B number  │Set ERRORLEVEL to given number.
EXIT number     │Ends cmd.exe and set its returning ERRORLEVEL value to given number.
START command   │If command is started, not change ERRORLEVEL; otherwise, set ERRORLEVEL = 9059.
START /WAIT bat |When the started Batch file end, set ERRORLEVEL = value from 'EXIT number' commmand.
notExist        │If a non-existent command is entered for execution, set ERRORLEVEL = 9009.
VER             │Set ERRORLEVEL = 0 almost always. If /? parameter is given, not change ERRORLEVEL.

終了コード管理

ERRORLEVEL値をテストするには、IF ERRORLEVEL / IF %ERRORLEVEL%コマンドを使用する方法と、command && thenCmd when ERRORLEVEL is 0 || elseCmd when ERRORLEVEL is not 0コンストラクトを使用する方法の2つがあります。ただし、特定の特定のコマンドおよびリダイレクトエラーは、2番目のケースでのみ機能する値を返し、ERRORLEVELにnot反映されます。この値を「終了コード」と呼ぶ場合があります。この終了コードがゼロでない場合、elseCmd部分の表1のコマンドを実行するERRORLEVELに渡すことができます。この問題の詳細については、 この投稿 をご覧ください。

表5-終了コードを設定するコマンドまたは機能

Feature      │ Set Exit Code to = when
─────────────┼─────────────────────────────────────────────────────────────────────────
command      │1 = Command not exist (when ERRORLEVEL = 9009).
redirection  │1 = File not exists in "<", path not exists or access denied in ">" ">>".
drive:       |1 = Drive unit not exists.
POPD         |1 = No matching PUSHD was previously executed.
RD           │1 = Bad switch given, 2 = Directory not found, 5 = Access denied,
             │32 = Directory in use, 145 = Directory not empty.
FOR /F       │1 = No data was processed.

たとえば、リダイレクトエラーが発生したかどうかをテストするには、次を使用します。

command > C:\Path\that\does\not\exist\file.txt || rem
if errorlevel 1 echo Previous redirection failed

この例では、remコマンドを使用して終了コードをERRORLEVELにコピーしますが、ERRORLEVELを保持する他の内部コマンドを使用できます(FORおよびIFを除く) 。

ドライブユニットが存在するかどうかをテストするには:

U: || rem
if errorlevel 1 echo Previous set current drive to U: unit failed

その他の例:

rd c:\Some\directory 2> NUL || rem
if %errorlevel% equ 0 (
   echo Directory deleted
) else if %errorlevel% equ 2 (
   echo Directory not found
) else if %errorlevel% equ 5 (
   echo Can not access the directory, check rights
) else if %errorlevel% equ 32 (
   echo Can not delete current directory
) else if %errorlevel% equ 145 (
   echo Directory is not empty, use /S switch
)


(for /F "options" %%a in (input.txt) do echo %%a) || rem
if errorlevel 1 echo Previous FOR didn't processed any value
33
Aacini