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
  )
)


Windows コマンドプロンプト ポケットリファレンス
4774149543

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は、推奨しないので説明は省略。


システム環境変数とユーザ環境変数の違いについてざっくり説明する。

ユーザ環境変数は、サービスなどユーザがログインしてないくて
動作しているプロセスにも有効になる。
ユーザ環境変数は、ログインしてから起動するプロセスに対して有効になる。

では、同じ環境変数名で異なる値が設定されていたらどうなるか?

実験

設定値

以下を設定する

環境変数 システム環境変数の値 ユーザ環境変数の値
TEST_OVERWRITE SYSTEM USER
TEST_ADD %TEST_ADD%;SYSTEM %TEST_ADD%;USER
設定方法

コントロールパネル > パフォーマンスとメンテナンス > システム
もしくは
エクスプローラからマイコンピューターを右クリック > プロパティ

システムのプロパティから
「詳細設定」タブの環境変数を選択


結果

環境変数 サービス(*1)での値 アプリケーション(*2)での値
TEST_OVERWRITE SYSTEM USER
TEST_ADD SYSTEM SYSTEM;USER

*1 apache で Process Walkerで確認
*2 コマンドプロンプトでsetコマンドで確認

注意事項

起動したままのプロセスには有効にならない。
分かっているつもりでも結構以下ではまる。

サービス

サービスは、システム環境変数に変更して、サービスを再起動しても有効にならなず
OS起動時のシステム環境変数のままのものもある。
サービスは、サービスマネージャー(service.exe)から起動される。サービスマネージャーは
起動したままであり、OS起動時のシステム環境変数のままであるからである。
(サービスプログラムの中で起動環境変数を取得して、新たに設定して子プロセスを起動してれば問題ない)
サービスの環境変数は、いつのものが有効になっているかが分かりにくい。
TEMP、TMPなどは、システム環境変数とユーザ環境変数で値が異なる。
いつのどの環境変数が有効になっているかProcess Walker、Process Explorerなどのツールを
使って確認したほうがいいだろう。

クイック起動やランチャー

クイック起動やランチャーで起動すると、ユーザ環境変数を変更して、新しくアプリケーションを起動して有効にならず
ログインした時のユーザ環境変数のままである。
アプリケーションは、ランチャーから起動される。ランチャーは起動したままであり、ユーザログイン時
のユーザ環境変数のままであるから
クイック起動からコマンドプロンプトを起動して、環境変数が有効にならないんだけど・・・
なんて質問を結構された記憶がある。

3.環境変数 (4)環境変数一覧 〜全部見せます〜 【コマンドプロンプト、バッチファイルを使わなきゃならなくなった人向けのメモ】


環境変数の一覧を表示する
(Unixだとenvコマンド)

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ぐらい。




Windows コマンドプロンプト ポケットリファレンス
4774149543

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

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 が定義されていません


初歩的なことを書いたら、食物連鎖じゃないけど、どんどん役に
立つ記事につながっていかないかな。




Windows コマンドプロンプト ポケットリファレンス
4774149543