こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

終了コード errorlevel の考え方について

こんばんは。
OSはWindowsXP Proを使っています。
テキストファイルに書いてある値を
終了コードにするバッチファイルを作成しました。
以下の2ファイルを同じディレクトリに保存します。

test.txt
┌--------┐
  1
└--------┘

test.bat
┌---------------------------------------┐
  @echo off

  find "0" test.txt
  if not errorlevel 1 exit /b 0

  find "1" test.txt
  if not errorlevel 1 exit /b 1

  echo テキストは0~1の値ではありません。
  exit /b 2
└---------------------------------------┘

この状態で次のように実行します

(1)
C:\>test.bat
---------- TEST.TXT
---------- TEST.TXT
1

(2)
C:\>echo %errorlevel%
1

(3)
C:\>set errorlevel=0

(4)
C:\>echo %errorlevel%
0

※ここでtest.txtの中の数字を2にします。

(5)
C:\>test.bat
---------- TEST.TXT
---------- TEST.TXT
テキストは0~1の値ではありません。

(6)
C:\>echo %errorlevel%
0

(7)
C:\>set errorlevel=

(8)
C:\>echo %errorlevel%
2

となります。

(2)の結果から、(1)で実行した「exit /b 1」でerrorlevelに1が格納されることが判ります。
しかし、(6)の結果から、(3)で実行した「set errorlevel=0」が
(5)で実行した「exit /b 2」より優先されていることが判ります。
しかし(7)でerrorlevelの値を消去したように思われますが、
(8)の結果から、(3)のセットを消去しつつ(5)で実行した「exit /b 2」を記憶しているように見えます。

この挙動について、どのように理解すれば良いのでしょうか。
また「exit /b ○」と「set errorlevel=○」でセットする違いについて教えて頂ければと思います。
お願いします。

投稿日時 - 2009-08-12 22:27:18

QNo.5202707

暇なときに回答ください

このQ&Aは役に立ちましたか?

6人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

ERRORLEVELは、一般の環境変数と異なり、SET で値を代入してはいけません。(参考: set /? で表示される最終ページ)
SET を使うと一般の環境変数となってしまい、次にSETするまで値は変わりません。コマンドの実行結果と切り離されると言うことです。
%ERRORLEVEL%は、環境変数ERRORLEVELがセットされていないときに限って、直前のコマンドの実行結果ステータスに置換されます。
(7)によってアンセットされたので、再びコマンド実行結果を表すようになりました(8)。

環境変数ERRORLEVELに値がセットされているかどうかは、SET ERRORLEVELでわかります。つまり、%ERRORLEVEL%をコマンドの実行結果として使うためには、

C:\>set errorlevel
環境変数 errorlevel が定義されていません

という状態でないといけません。
%ERRORLEVEL%をゼロにしたければ、
C:\>cd
とかの正常終了するコマンドを打てばいいです(ECHOは除く)。

投稿日時 - 2009-08-12 23:11:17

お礼

回答ありがとうございます。

「一般の環境変数」という考え方が判りませんが、変数と考えれば良いのでしょうか。

「set /?」で
--------------------------------------------------------------
コマンド拡張機能が有効な場合、
SETによって表示される変数の一覧には現れない
いくつかの動的な環境変数があります。
これらの変数の値は、変数の値が展開されるときに動的に計算されます。
ユーザーがこれらの名前の変数を明示的に定義する場合、
その定義は下記の動的な定義を無効にします。
--------------------------------------------------------------
とありました。
その文章以下に書いてある%CD%~%CMDCMDLINE%はSETで値を設定してはいけないということですね。

・ERRORLEVELの値は実行結果により、動的に値が変更される。
・SETで値を代入すると、動的に設定された値よりSETで代入した値を優先して参照する。
という理解です。

「set errorlevel=○」で設定した値を消去するには「set errorlevel=」
「exit /b ○」で設定した値を消去するには「C:\>cd」
を行えばよいのですね。

cd以外でも
C:\>dir
を実行した所、「exit /b ○」の終了コードが無効になったことを確認しました。

投稿日時 - 2009-08-13 10:06:04

ANo.1

set errorlevel=○
とすると環境変数errorlevelの値がセットされる。
exit /b ○
とするとシステム変数errorlevelの値がセットされる。これは自動的に環境変数errorlevelにもセットされる。

echo %errorlevel%
としたとき環境変数errorlevelがセットされていればその値を書く。セットされていなければシステム変数errorlevelその値を書く。

set errorlevel=
としたとき消去されるのは環境変数errorlevelの値である。

投稿日時 - 2009-08-12 22:53:25

補足

回答ありがとうございます。

「環境変数」と「システム変数」という違いがあるのですね。
どのような違いがあるのか、今の私にはまだ判らないのですが。

「コントロールパネル」→「システム」→「詳細設定」→「環境変数」→「システム環境変数」
に「変数名」「変数値」を設定した所、回答者様がおっしゃる所の環境変数の値になりました。

「echo %errorlevel%」で
環境変数がセットされていればその値を、セットされていなければシステム変数を表示する、
は理解しました。

一つだけ腑に落ちないのが
(4)で環境変数に0がセットされましたが、
(6)で0を表示しているということは
(5)ではシステム変数に2をセットしているが、環境変数には2をセットしていないことになります。
このことが

>exit /b ○
>とするとシステム変数errorlevelの値がセットされる。これは自動的に環境変数errorlevelにもセットされる。

に矛盾していると考えました。お言葉を返すようですみません。

投稿日時 - 2009-08-13 10:54:19

あなたにオススメの質問