4.基本文法 (1)if文、else文 〜もしもー、それ以外ならばー〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
if文とelse文
else文ももちろん使える。
しばらく使えないと思い込んでた。
ifのヘルプにきっちり書いてあるんだよね。。。
以下の環境変数を設定してることを前提。
set ARG1=A
set ARG2=A
正しい使い方1
if-else-normal1.bat
IF {%ARG1%}=={%ARG2%} ( echo equal. ) ELSE ( echo not equal. )
実行結果
D:\MyDoc\work\#blog\コマンドプロンプト>IF {A} == {A} (echo equal. ) ELSE (echo not equal. ) equal.
実行時には正しい使い方2と同じに解釈される。
でも、この書き方の方が読みやすいので、こちらを使った方がよい。
正しい使い方2
if-else-normal2.bat
IF {%ARG1%}=={%ARG2%} (echo equal.) ELSE (echo not equal.)
実行結果
D:\MyDoc\work\#blog\コマンドプロンプト>IF {A} == {A} (echo eqlual. ) ELSE (echo not equal. ) eqlual.
実行するコマンドを()で囲むのがポイント
誤った使い方1
if-else-error1.bat
IF {%ARG1%}=={%ARG2%} echo equal. ELSE echo not equal.
実行結果
D:\MyDoc\work\#blog\コマンドプロンプト>IF {A} == {A} echo eqlual. ELSE echo not equal. eqlual. ELSE echo not equal.
ヘルプには以下の説明がある。
del コマンドは、改行で終了しなければならないため、次の例は、正しく動作し
ません:
delだけでなく、コマンドは、改行で終わるまでをパラメータとして認識してしまうから
ELSE以降もコマンドパラメータとして認識されてしまっている。
誤った使い方2
if-else-error2.bat
IF {%ARG1%}=={%ARG2%} echo equal. ELSE echo not equal.
実行結果
D:\MyDoc\work\#blog\コマンドプロンプト>ELSE echo not equal. 'ELSE' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。
ELSEをコマンドとして認識してしまっているのでNG
ifはコマンドだがelseは節(ifのコマンドオプション)なので誤解しやすい
入れ子も可能
set /A TEST1=%random%/10000 set /A TEST2=%random%/10000 IF {%TEST1%}=={1} ( IF {%TEST2%}=={2} ( echo TEST1=1,TEST2=2 ) ELSE ( echo TEST1=1,TEST2!=2 ) ) ELSE ( IF {%TEST2%}=={2} ( echo TEST1!=1,TEST2=2 ) ELSE ( echo TEST1!=1,TEST2!=2 ) )
3.環境変数 (6)x64とx86の環境変数の違い 〜x64はx86とは違うんです。x86とは〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
x64とx86の環境変数の違い。
Windows Server2003 x64版で確認
デフォルトではなく、Visual Studio2005、Officeなど諸々が
インストールされている環境
確認結果
64bitのコマンドプロンプト
C:\>set |findstr "x86 64 32" ComSpec=C:\WINDOWS\system32\cmd.exe CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files Path=C:\Program Files (x86)\Windows Resource Kits\Tools\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\ System32\Wbem;C:\Program Files (x86)\Log Parser 2.2;C:\Program Files\Microsoft Network Monitor 3\;C :\WINDOWS\system32\kktools PROCESSOR_ARCHITECTURE=AMD64 PROCESSOR_IDENTIFIER=EM64T Family 15 Model 4 Stepping 10, GenuineIntel ProgramFiles(x86)=C:\Program Files (x86) VS80COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\
32bitのコマンドプロンプト
C:\>set |findstr "x86 64 32" ComSpec=C:\WINDOWS\system32\cmd.exe CommonProgramFiles=C:\Program Files (x86)\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files Path=C:\Program Files (x86)\Windows Resource Kits\Tools\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\ System32\Wbem;C:\Program Files (x86)\Log Parser 2.2;C:\Program Files\Microsoft Network Monitor 3\;C :\WINDOWS\system32\kktools PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=AMD64 PROCESSOR_IDENTIFIER=EM64T Family 15 Model 4 Stepping 10, GenuineIntel ProgramFiles=C:\Program Files (x86) ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files VS80COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 8\Common7\Tools\
x64版の32bitコマンドプロンプトには、XXXX6432っていう変な環境変数がある。
「ComSpec=C:\WINDOWS\system32\cmd.exe」これはおかしい気がするんだけどなぁ
動作してるのは「C:\WINDOWS\systemWow64\cmd.exe」のはず。
でもこう表示される。
前にも書いたが、x64版を使ってて、64bitか32bitかを切り分けるなら
PROCESSOR_ARCHITECTUREを参照する。
3.環境変数 (5)起動時に有効になる環境変数 〜人生と環境変数は、順番が大事〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
Windows XP以降だと環境変数は、以下で設定できる。
setコマンドについては説明済み、
autoexec.batは、推奨しないので説明は省略。
システム環境変数とユーザ環境変数の違いについてざっくり説明する。
ユーザ環境変数は、サービスなどユーザがログインしてないくて
動作しているプロセスにも有効になる。
ユーザ環境変数は、ログインしてから起動するプロセスに対して有効になる。
では、同じ環境変数名で異なる値が設定されていたらどうなるか?
実験
結果
環境変数名 | サービス(*1)での値 | アプリケーション(*2)での値 |
TEST_OVERWRITE | SYSTEM | USER |
TEST_ADD | SYSTEM | SYSTEM;USER |
注意事項
起動したままのプロセスには有効にならない。
分かっているつもりでも結構以下ではまる。
サービス
サービスは、システム環境変数に変更して、サービスを再起動しても有効にならなず、
OS起動時のシステム環境変数のままのものもある。
サービスは、サービスマネージャー(service.exe)から起動される。サービスマネージャーは
起動したままであり、OS起動時のシステム環境変数のままであるからである。
(サービスプログラムの中で起動環境変数を取得して、新たに設定して子プロセスを起動してれば問題ない)
サービスの環境変数は、いつのものが有効になっているかが分かりにくい。
TEMP、TMPなどは、システム環境変数とユーザ環境変数で値が異なる。
いつのどの環境変数が有効になっているかProcess Walker、Process Explorerなどのツールを
使って確認したほうがいいだろう。
3.環境変数 (4)環境変数一覧 〜全部見せます〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
Windows XPで設定されているデフォルト環境変数一覧
C:\>set ALLUSERSPROFILE=C:\Documents and Settings\All Users APPDATA=C:\Documents and Settings\Administrator\Application Data CommonProgramFiles=C:\Program Files\Common Files COMPUTERNAME=SANDBOX ComSpec=C:\WINDOWS\system32\cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Documents and Settings\Administrator LOGONSERVER=\\SANDBOX NUMBER_OF_PROCESSORS=1 OS=Windows_NT Path=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 8, GenuineIntel PROCESSOR_LEVEL=15 PROCESSOR_REVISION=0408 ProgramFiles=C:\Program Files PROMPT=$P$G SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\WINDOWS TEMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp TMP=C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp USERDOMAIN=SANDBOX USERNAME=Administrator USERPROFILE=C:\Documents and Settings\Administrator windir=C:\WINDOWS
よく参照するのは、SystemRoot,TEMP,TMPぐらいか。
(OSがx64版だとPROCESSOR_ARCHITECTUREで切り分けるために参照する)
デフォルトの環境変数でよく設定を変更するのはPATHぐらい。
3.環境変数 (3)ローカル環境変数を使用する 〜ここだけの話〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
でも、バッチファイルで設定した環境変数がそのまま
コマンドプロンプトに残っているとなにかと都合が悪い。
PATHなどはバッチファイルごとに指定した場合もある。
そのために使うのがsetlocalコマンドとendlocalコマンドである
これで環境変数のスコープを狭めることができる
テスト用バッチファイル
@echo off echo 変数確認 set GLOBAL set LOCAL echo. echo グローバル変数設定 set GLOBAL=hoge echo. setlocal echo setlocal echo 変数確認 set LOCAL set GLOBAL echo ローカル変数設定 set LOCAL=fuga echo 変数確認 set LOCAL set GLOBAL endlocal echo endlocal echo. echo 変数確認 set GLOBAL set LOCAL echo. setlocal echo setlocal echo 変数確認 set LOCAL set GLOBAL echo ローカル変数設定 set LOCAL=foo echo 変数確認 set LOCAL set GLOBAL endlocal echo endlocal echo. echo 変数確認 set LOCAL set GLOBAL echo.
実行結果
変数確認 環境変数 GLOBAL が定義されていません 環境変数 LOCAL が定義されていません グローバル変数設定 setlocal 変数確認 環境変数 LOCAL が定義されていません GLOBAL=hoge ローカル変数設定 変数確認 LOCAL=fuga GLOBAL=hoge endlocal 変数確認 GLOBAL=hoge 環境変数 LOCAL が定義されていません setlocal 変数確認 環境変数 LOCAL が定義されていません GLOBAL=hoge ローカル変数設定 変数確認 LOCAL=foo GLOBAL=hoge endlocal 変数確認 環境変数 LOCAL が定義されていません GLOBAL=hoge
setlocalコマンドとendlocalコマンドの間だけ有効になる
3.環境変数 (2)環境変数の計算 〜コマンドプロンプトで計算するか普通?〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
コマンドプロンプトでは変数はなく、全て環境変数になる。
これだと計算ができないように思えるが、コマンドプロンプトでも
ちゃんと計算ができる。
(でも、普段使場面はループ処理でのインクリメントぐらいだろ。)
SET /A 式
計算
/Aをつけないと文字列になってしまう
c:\>set X=3*4 c:\>set X X=3*4
足し算
c:\>set /A X=3+4 7 c:\>set X X=7
最大値はINT_MAX
c:\>set /A X=2147483647 2147483647 c:\>set /A X=2147483647+1 -2147483648
引き算
c:\>set /A X=4-3 1 c:\>set X X=1
最小値はINT_MIN
c:\>set /A X=-2147483648 -2147483648 c:\>set /A X=-2147483648-1 2147483647
掛け算
c:\>set /A Y=3*4 12 c:\>set Y Y=12
最大値はINT_MAXなので以下も0になる
c:\>set /A X=256*256*256*256 0
割り算
c:\>set /A X=12/3 4 c:\>set X X=4
0で割るとちゃんと0除算エラーになる
c:\>set /A X=1/0 0 除算エラーです。
少数は切り捨て
c:\>set /A X=11/3 3 c:\>set /A X=11/3*3 9
同じ変数を使った計算
c:\>set /A X=1 1 c:\>set /A X=%X%+1 2
3.環境変数 (1)環境変数の使い方 〜意外に削除の仕方はしらない人が多い〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】
環境変数を設定、表示、削除したい。
コマンドプロンプトでは、変数と環境変数の区別はない。
あるのは環境変数だけ。
これがUnnixと異なる。
環境変数の設定
c:\>set XYZ=hoge
環境変数の表示
SETコマンドで表示
大文字小文字の区別はない。
c:\>set XYZ XYZ=hoge c:\>set xyz XYZ=hoge
プレフィックスが一致するものが表示される。
c:\>set X XYZ=hoge
複数合致した場合は、全て表示される
c:\>set A ALLUSERSPROFILE=C:\Documents and Settings\All Users APPDATA=C:\Documents and Settings\orangeclover\Application Data APR_ICONV_PATH=C:\usr\opt\Subversion\iconv
ckwを使うとこの仕様が異なりプレフィックスの一致では表示されない。
[c:\]set A A=
%で展開して表示
大文字小文字の区別はない。
c:\>echo %XYZ% hoge c:\>echo %xyz% hoge
環境変数の削除
最初使い始めたころは、なんでunsetってないだんろうと
環境変数は消せない!って思ってた。
仕方がないから以下のようにごまかしてた。
SET XYZ=""
でも消せるんだよね。。。
SETのヘルプより
SET [変数名=[文字列]] ↑ これがポイント
SET 変数名=まで書くと消せる。
なんか変なの。
c:\>set XYZ=
確認
c:\>echo %XYZ% %XYZ% c:\>set XYZ 環境変数 XYZ が定義されていません c:\>set X 環境変数 X が定義されていません
初歩的なことを書いたら、食物連鎖じゃないけど、どんどん役に
立つ記事につながっていかないかな。