バッチファイルでの変数の利用と遅延環境変数展開(SETLOCAL)

広告

バッチファイル内では変数を使用して値を保存したり、変数に保存した値を参照することができます。ここではバッチファイル内で変数を利用する方法について解説します。あわせてバッチファイルで変数を利用する場合に注意が必要な即時変数展開と遅延環境変数展開に関しても説明を行います。

変数の基本的な使い方

バッチファイルで変数を使用する場合、環境変数を使って値の保存を行います。書式は次の通りです。

SET [変数名=[文字列]]

この書式は環境変数に値を設定するのとまったく同じ書式です。

例えば変数名 msg に文字列 "Hello" を保存するには次のように実行します。

set msg=Hello

バッチファイルの中で変数に保存した値を参照するには次のように行います。

%変数名%

この書式は環境変数名の値を参照するときとまったく同じです。

それではテストを行うために次のような簡単なバッチファイル test.bat を c:\test\ に作成しました。

@echo off

set msg=Hello
for /l %%n in (1,1,10) do (
  echo %msg%
)

※ バッチファイルの中で for コマンドを使用する方法については「バッチファイルで繰り返し処理を使う(FOR)」を参照されてください。

バッチファイル test.bat を実行すると変数に保存した文字列 "Hello" を 10 回画面に出力します。

変数の基本的な使い方(1)

このように環境変数と同じ書式を使ってバッチファイルの中で変数を利用することができます。

即時変数展開と遅延環境変数展開

バッチファイルの中で、 for 文や if 文などで括弧で囲まれたブロックの中で変数を利用するときに注意が必要なのが即時変数展開と遅延環境変数展開の違いについてです。まず簡単な例を見てください。

@echo off

for %%s in (Blue Red Green) do (
  echo %%s
)

このバッチファイルでは、変数 s に Blue, Red, Green を順に設定しながら、その変数の値を出力しています。実際に実行すると次のように出力されます。

即時変数展開と遅延環境変数展開(1)

ではこのバッチファイルを次のように変更してみます。

@echo off

set col=Yello
for %%s in (Blue Red Green) do (
  set col=%%s
  echo %col%
)
echo %col%

先ほどとの違いは、いったん変数 col に変数 s の値を設定し、そのあとで変数 col の値を出力している点です。ただこのバッチファイルを実行すると次のような結果となります。

即時変数展開と遅延環境変数展開(2)

for 文の中で変数 col に都度値を設定しているはずなのに、変数の値を出力すると初期値として設定した値のままとなっています。

実はバッチファイルでは、コマンドが実行される前の「コマンド行の解析時」に変数の値が展開されます。通常のコマンドは 1 行ごとに解析されますが、 for 文や if 文などで括弧で囲まれたブロックがある場合は、そのブロック全体がまとめて解析され、その時点で変数の値が展開されます。

そのため、ブロック内で変数の値を変更する処理を行っても、 %変数% のような通常の変数参照では解析時の値が使用されるため、ブロック内では変数の値が変わっていないように見える場合があります。

このように、コマンド実行前の解析時に変数の値が展開される方式を「即時変数展開」と呼びます。バッチファイルではデフォルトでこの即時変数展開が使用されます。先ほどのサンプルでいえば、次のように記述したのと同じ結果となります。

@echo off

set col=Yello
for %%s in (Blue Red Green) do (
  set col=%%s
  echo Yello
)
echo %col%

ただしループの中で変数 col への値の設定は行われているので、最後の echo で変数 col の値を出力すると、ループの中で最後に変数 col に設定された "Green" が出力されます。

遅延環境変数展開を有効にする

即時変数展開のままでは、for 文や if 文の括弧内などで変数の値を変更した場合に扱いづらくなることがあります。そのため、変数の値の展開をバッチファイルの実行時に行うように設定することができます。この仕組みを「遅延環境変数展開」といいます。

変更する場合は SETLOCAL コマンドを使用します。具体的には次のように実行します。

SETLOCAL ENABLEDELAYEDEXPANSION
SETLOCAL DISABLEDELAYEDEXPANSIO

SETLOCAL コマンドをオプション引数 ENABLEDELAYEDEXPANSION を付けて実行すると、遅延環境変数展開が有効になります。逆に DISABLEDELAYEDEXPANSIO を付けて実行すると遅延環境変数展開が無効となります。デフォルトでは無効となっています。

バッチファイルで遅延環境変数展開を有効にするには、有効にしたい位置で SETLOCAL コマンドを実行してください。

@echo off
setlocal EnableDelayedExpansion

注意点として、遅延環境変数展開を有効にすると !変数! という形式で変数を実行時に展開できます。特に for 文や if 文の括弧内などで変数の値が変化する場合は、%変数% ではなく !変数! を使用します。

!変数名!

それでは先ほどのサンプルを変更してみます。

@echo off
setlocal EnableDelayedExpansion

set col=Yello
for %%s in (Blue Red Green) do (
  set col=%%s
  echo !col!
)
echo %col%

このバッチファイルを実行すると次のような結果となります。

即時変数展開と遅延環境変数展開(3)

遅延環境変数展開を有効にすることで、 for 文などのブロック内であっても変数の値を実行時に参照することができるようになりました。

-- --

バッチファイル内で変数を利用する方法、およびバッチファイルで変数を利用する場合に注意が必要な即時変数展開と遅延環境変数展開に関して解説しました。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。