はじめての親子ハイキングに挑戦!! >>

こんばんは。
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=○」でセットする違いについて教えて頂ければと思います。
お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

ERRORLEVELは、一般の環境変数と異なり、SET で値を代入してはいけません。

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

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

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

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

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

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

「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

set errorlevel=○


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

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

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

この回答への補足

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

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

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

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

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

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

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

補足日時:2009/08/13 10:54
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QコマンドプロンプトのERRORLEVELについて!

コマンドプロンプトの記述で、ERRORLEVELというのがありますが
そのERRORLEVELが、0の場合は正常終了と考えていいのでしょうか?

Aベストアンサー

>if not ERRORLEVEL 1 goto aaa
>教えていただいた上記記述なんですが、
>1じゃないということは、2~255も含まれるのではないのでしょうか?
>素朴な疑問ですいません。

if文の文法については、if /? で調べてください。

if ERRORLEVEL 1 goto aaa は、ERRORLEVEL が1以上の時にgoto aaaするという意味です。ということを#4の人が書いてるのですが・・・
従って、その否定である、
if not ERRORLEVEL 1 goto aaa は、ERRORLEVEL が1未満つまり0のときにgoto aaaします(負になることはないので)。

Qbatである文字列内に特定の文字列が含まれているか確認したい

batファイルの中である変数「abc」の中に「test」という文字が含まれていたら○○を行なうという分岐を作成したいのですが、どのように行なえばよいのでしょうか?

そのまま、ずばりのお答えお待ちしております。

よろしくお願い致します。

Aベストアンサー

大文字小文字を区別しなくていいなら、

if not "%abc:test=%" == "%abc%" echo 含まれていた

区別するなら、

echo %abc% | find "test" >NUL
if not ERRORLEVEL 1 echo 含まれていた

Qバッチ処理でファイルの中身を変数に入れるやり方

あるファイルの中には1行の文字列があります。
このファイルをバッチで読み取り、変数に設定したいです。

例:
test.txt
abcacbacbacbacbacbacbacbacb

test,bat
set DATA=[test.txtを読み込んだ値]

よろしくお願い致します。

Aベストアンサー

これですね。

参考URL:http://www.upken.jp/kb/dqvgHNRUxwFDkmtoqEwfXHUjDrevNv.html

Qbatファイルの結果をテキストに吐き出すには?

以下のようなWindowsユーザーのパスワード変更batの結果(正常に出来たかどうか?)をCドライブに吐き出したいのですが、どうbatファイルを書き換えればよいでしょうか?
(とりあえず以下の内容でbatをたたいたのですが、うまく結果が出ません。。。)

henkou.bat
--------------------------------------
net user "test user1" ps123456 /domain
net user "test user2" ps456789 /domain
henkou.bat > c:\henkou結果.txt
pause
--------------------------------------

吐き出されたhenkou結果.txt
--------------------------------------
C:\>net user "test user1" ps123456 /domain
--------------------------------------

DOS画面(吐き出したいもの)
--------------------------------------
C:\>net user "test user1" ps123456 /domain
コマンドは正常に終了しました。

C:\>net user "test user2" ps456789 /domain
コマンドは正常に終了しました。

C:\>henkou.bat 1>c:\henkou結果.txt
--------------------------------------

以下のようなWindowsユーザーのパスワード変更batの結果(正常に出来たかどうか?)をCドライブに吐き出したいのですが、どうbatファイルを書き換えればよいでしょうか?
(とりあえず以下の内容でbatをたたいたのですが、うまく結果が出ません。。。)

henkou.bat
--------------------------------------
net user "test user1" ps123456 /domain
net user "test user2" ps456789 /domain
henkou.bat > c:\henkou結果.txt
pause
--------------------------------------

吐き出されたhenkou結果.t...続きを読む

Aベストアンサー

henkou.bat
--------------------------------------
@ECHO OFF

IF NOT EXIST %temp%\Redirect.txt GOTO REDIREXEC

@ECHO ON

net user "test user1" ps123456 /domain
net user "test user2" ps456789 /domain

@ECHO OFF

GOTO END

:REDIREXEC

ECHO REDIRECT > %temp%\Redirect.txt

CALL TEST.BAT > c:\henkou結果.txt

DEL %temp%\Redirect.txt

PAUSE

:END
--------------------------------------

こんな感じでどうでしょうか。

QDOSコマンドで、標準出力を出力しないようにするには?

Windowsのバッチファイルでコマンドを実行する際、標準出力をディスプレイに表示したくないのですが、どのようにするのが、一般的なのでしょうか?
CDで実行するので、ファイルに出力はしたくありません。
UNIXとかだと、nullにパイプするようなのですが…。

Aベストアンサー

>UNIXとかだと、nullにパイプするようなのですが…。

リダイレクトですね。

同様です。
標準出力だけなら「c:\> command > nul」
エラー出力もなら「c:\> command > nul 2>&1」

Qバッチファイルで昨日の日付を取得

すみません、どなたか教えて下さい。

バッチファイルの記述で、昨日の日付を取得する方法を教えて下さい。
今日の日付は下記のように取得しています。

rem 日時変数の取得
for /f "tokens=1-3 delims=/" %%a in ('echo %date:~-10%') do (set YYYYMMDD=%%a%%b%%c
)

Aベストアンサー

:: ----- prevdate.bat はじめ -----
@echo off
::今日の日付を取得
set yy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
echo 今日は、%yy%年%mm%月%dd%日です。

::1日前の日付を計算する
set /a dd=%dd%-1
set dd=00%dd%
set dd=%dd:~-2%
set /a ymod=%yy% %% 4
if %dd%==00 (
if %mm%==01 (set mm=12&& set dd=31&& set /a yy=%yy%-1)
if %mm%==02 (set mm=01&& set dd=31)
if %mm%==03 (set mm=02&& set dd=28&& if %ymod%==0 (set dd=29))
if %mm%==04 (set mm=03&& set dd=31)
if %mm%==05 (set mm=04&& set dd=30)
if %mm%==06 (set mm=05&& set dd=31)
if %mm%==07 (set mm=06&& set dd=30)
if %mm%==08 (set mm=07&& set dd=31)
if %mm%==09 (set mm=08&& set dd=31)
if %mm%==10 (set mm=09&& set dd=30)
if %mm%==11 (set mm=10&& set dd=31)
if %mm%==12 (set mm=11&& set dd=30)
)
echo 昨日は、%yy%年%mm%月%dd%日です。

echo.
pause
:: ----- prevdate.bat おわり -----

参考URL:http://www.atmarkit.co.jp/fwin2k/win2ktips/419batchdate/batchdate.html

:: ----- prevdate.bat はじめ -----
@echo off
::今日の日付を取得
set yy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
echo 今日は、%yy%年%mm%月%dd%日です。

::1日前の日付を計算する
set /a dd=%dd%-1
set dd=00%dd%
set dd=%dd:~-2%
set /a ymod=%yy% %% 4
if %dd%==00 (
if %mm%==01 (set mm=12&& set dd=31&& set /a yy=%yy%-1)
if %mm%==02 (set mm=01&& set dd=31)
if %mm%==03 (set mm=02&& set dd=28&& if %ymod%==0 (set dd=29))
if %mm%==04 (set mm=03&& set dd=31)
if...続きを読む

QFOR文内でサブルーチンをCALLした際の、ERRORLEVELの取得

ファイルをコピーしてからFOR文により6回処理を繰り返すような
バッチファイルを作成しようと思っています。
そのFOR文内でコールしたサブルーチンのERRORLEVELがうまく取得できません。ファイルコピーをしなければ値が取得できるのですが。。。
何が 原因なのか皆目見当つかずで行き詰ってしまいました。
どなたか 教えてください。 宜しく御願いします。

@echo off
copy test.txt test.txt.bak

for /L %%A in (0,1,5) do (
call :test
echo 戻り値:%ERRORLEVEL%
)
:test
exit /b 99

Aベストアンサー

環境変数は、一行ごとに解釈されるようです。
%ERRORLEVEL%も同様です。
for ( ... )は、一文とみなされ、for文内でERROELEVELが変わっていても、
echo文の%ERRORLEVEL%は、for文実行前の値となってしまいます。
実際には、ERRORLEVELはセットされており、
if errorlevel では、ちゃんと機能します。

実行中に変更される環境変数を使用するためには、
遅延環境変数という機能があります。

cmd /v:onとしてコマンドプロンプトを起動後、
変数を、!ERROELEVEL! と指定することで、実行中に変更された環境変数を使用することができます。

以上

Qバッチファイル 文字列にスペースがある場合

for /f %%A in ('dir /b /s c:\a aa*.pdf') do copy "%%A" D:\

これはcドライブのa aaというフォルダ名の中を検索するコードですが、
フォルダ名にスペースがあるため、うまく動きません。

"a aa"のように""で囲ってみましたが、駄目でした。

どうすれば良いのか、教えていただきたいので、お願いします。

Aベストアンサー

for /f %%A in ('dir /b /s c:\"a aa"\*.pdf') do echo copy "%%A" D:\
のようにecho でどのようなコマンドが実行されているか確認しましょう。

この記述ではdirコマンドで表示されるパスの中に空白があるため %%A には空白までの文字列しか代入されません。
以下のように修正して試してみてください。

for /f "delims=" %%A in ('dir /b /s c:\"a aa"\*.pdf') do copy "%%A" D:\

Qコマンドプロンプトの「%1」と「%~1」の違いがわからない

コマンドプロンプトの「%1」と「%~1」の違いがわからない
このサイトにhttp://ykr414.com/dos/bat.html
%~1は「全ての引用句(")を削除して%1を展開する。」とありますがよくわかりません。

%1は入力されたファイルのフルパスだと思っているのですけど。
"%1"=%~1ということでしょうか。

Aベストアンサー

%1は、バッチファイルに指定された「第一引数」です。
バッチファイルに限らず、プログラムを実行するときには引数を指定することができます。
単純に関連づけて実行するとかバッチファイルのアイコンにファイルをにドラッグドロップするとかだと、引数は一つない場合が多いですが、
実際にはショートカットを作ったりコマンドプロンプトから指定するとか、二つ以上の引数を指定することができます。
その際、引数と引数の間はスペースで区切られます。(引数指定全体の文字列を、スペースで区切って各引数に分割する)

一方、例えば、マイドキュメントフォルダ「C:\Documents and Settings\ユーザー名\My Documents」を引数にを指定した場合、そのままだとフォルダ名に空白が入ってるので、
%1=C:\Documents
%2=and
%3=Settings\ユーザー名\My
%4=Documents
と、指定した一つの名前が複数の引数に分断されてしまします。

そこで、こういう場合には、ダブルクオートでファイル名を括ります。
プログラム起動時の引数に 「"C:\Documents and Settings\ユーザー名\My Documents"」
といった感じで、ダブルクオートを付けたものを指定すると、
%1="C:\Documents and Settings\ユーザー名\My Documents"
と、括られた部分がまとめて一つの引数と取り扱われるようになります。
そして、この時%~1は
%~1=C:\Documents and Settings\ユーザー名\My Documents
になります。

%1と%~1の使い分けですが、
引数をこのままファイル名として使う時は、%1をそのまま使えば問題ないのです。
(バッチファイルから別のプログラムを起動するときにファイル指定するとかだったら、
%1を使えば、ダブルクオート込みで渡されるので、そのまま一つの引数としてつかます)

一方、フォルダを指定してそのフォルダ下のファイル名を作る、といった処理をしようとする時には、
ダブルクオートが邪魔なので、そういう時は%~1を使います。
たとえば、指定した引数をフォルダとして、そのフォルダ下の「新規作成データ.txt」ファイルを表すフルパスのファイル名を作りたい場合、

単に
 「%1\新規作成データ.txt」とすると、「"C:\Documents and Settings\ユーザー名\My Documents"\新規作成データ.txt」になってしまいますが、

「"%~1\新規作成データ.txt"」とすれば「"C:\Documents and Settings\ユーザー名\My Documents\新規作成データ.txt"」という、正しくクオートされたファイル名を作ることができます。

%1は、バッチファイルに指定された「第一引数」です。
バッチファイルに限らず、プログラムを実行するときには引数を指定することができます。
単純に関連づけて実行するとかバッチファイルのアイコンにファイルをにドラッグドロップするとかだと、引数は一つない場合が多いですが、
実際にはショートカットを作ったりコマンドプロンプトから指定するとか、二つ以上の引数を指定することができます。
その際、引数と引数の間はスペースで区切られます。(引数指定全体の文字列を、スペースで区切って各引数に分割す...続きを読む

Qバッチでテキストファイルから任意の行のみ取得したい

batファイルを作成していて、
txtから特定の行のみをとりだし、変数に入れたいです。
どうもよくわからないので質問したいと思います。
まず以下の様なテキストファイルがあります。
-------------------
111
222
333
-------------------
実際の値、行数は違いますが、こんな感じに文字列が複数行並んでいます。

行いたい動作は、
-----------------------------------------
1.テキストファイルの1行目を変数Textに入れる(set Text=111)
2.変数Textを使用し色々処理をする
3.テキストファイルの2行目を変数Textに入れる(set Text=222)
4.変数Textを使用し色々処理をする
-----------------------------------------
コレを繰り返します。
2と4は同じ動作ですので、行数のカウンタを設定しループさせる予定です。
n行目を全て取り出す方法がわかれば行けると思うのですが、
どうも見つかりません。ご存知の方がいればお教え願いたいと思います。

batファイルを作成していて、
txtから特定の行のみをとりだし、変数に入れたいです。
どうもよくわからないので質問したいと思います。
まず以下の様なテキストファイルがあります。
-------------------
111
222
333
-------------------
実際の値、行数は違いますが、こんな感じに文字列が複数行並んでいます。

行いたい動作は、
-----------------------------------------
1.テキストファイルの1行目を変数Textに入れる(set Text=111)
2.変数Textを使用し色々処理をする
3.テキストファイルの2行目を変数T...続きを読む

Aベストアンサー

No3ですが、たぶん提示したスクリプトを見ると、ある事に気がつくはず?

findstr /n /r "." a.txt | findstr /r "^3:"

で3行目を表示してくれます。え!? それだけ。そうなんです

ただ、あと、先頭の”3:” をどうやって切り離すか? と言う問題にぶつかる。さらにファイルに先頭に”3:”があった場合、どうするのか? さらに、findstr の正規表現の動作が??? 表示すれるのはいいが、変数にどうやってセットするのか?

となる。結局 for 文を使いまわす事になります。

まあ、適当に改変して、上記の問題を解決してください。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング