コラム:遅延環境変数と環境変数の即時展開とは?

BASH,bat,バッチ

今回は変数について、少しコラムを書いていきます。

変数には種類がいくつかあるんですが、今回は遅延環境変数と環境変数の即時展開について解説します。

バッチファイルを作成する時に、変数が思ったとおりならない場合はこの変数のせいかもしれません。

遅延環境変数とは

遅延環境変数とは、

「バッチファイルで使う変数をコードを読み込むときではなくて、実際にその処理を実行するときに値と置き換えること」

です。

よくわかりませんよね。

最初に紛らわしいので、解説しますが、「遅延環境変数」という名前の変数はありません。

「遅延する変数」と補助語を入れて、環境という文字を削除するとわかりやすいかもしれません。

遅延する変数とは、変数を値に置き換えるのは、行を読み込んだときではなく、実際に実行するときに置き換えることを意味します。

遅延環境変数をバッチファイルで使われる変数の展開が遅延すると読み替えられます。

「変数の展開が遅延」を少し読み替えると、「変数を値に置き換えることが遅くなる」です。

いきなり文字だけで言われても、よく分からないですよね。わたしもわかりませんでした。

遅くなるということは、通常はどうなんでしょうか?

大丈夫です。順番に解説します。

変数、バッチファイルとは?

まず、変数は「値を入れておく箱」です。

バッチファイルは「コマンドプロンプトで実行できるコマンドをまとめて書いたファイル」です。

ちなみにバッチファイルで使われる変数は、基本的に環境変数です。環境変数とはosが動いている時の変数です。

osは今回詳しく解説しませんが、パソコンの中に最初に入る基本ソフトとだけと今回は思っててください

環境変数の即時展開とは

遅延環境変数の対になる言葉として、環境変数の即時展開があります。環境変数の即時展開は通常の変数のパターンです。

まず通常のパターンを事例で挙げます。

例えば、変数「hensu」に値「クマ」を設定して画面に表示する処理は

set hensu=クマ
echo %hensu%

と書きます。

一行目で変数「hensu」を値「クマ」としています。

二行目のechoで変数hensuを呼び出しています。

コマンドプロンプトの結果はこちら。クマと表示されましたね。

コマンド処理の結果

ちなみに1行目で変数を設定する際は%で囲まれていませんが、2行目で変数を呼び出す時は%で囲まれています。

この%はバッチファイルで変数の中身を見る時の使い方です。入門講義でも解説しました。

次にこちらのコードを実行します。これも通常時の変数です。

@echo off
set hensu=クマ
if "%hensu%" == "クマ" (
    set hensu=ネコ
    echo %hensu%
)
pause

各行の詳しい解説は後述しますが、このコードで大事なポイントは2行目から6行目までです。

set hensu=クマ

if “%hensu%” == “クマ” (

    set hensu=ネコ

    echo %hensu%

)

の部分です。

最後の変数はどうなるんですかね?

この処理は結果はこちら。

コマンド処理の結果

「クマ」なんですよ。表示が!

結構びっくりですよね。echoの前にset hensuで値をネコとしているのにです。

なぜ変数の値が変わらないのか、詳しく解説します。

2行目でset hensu=クマを設定しています。

3行目で

if “%hensu%” == “クマ” (

の条件判定です。

もし、変数『hensu』の中身が『クマ』なら、

という条件判定なので、結果は「〇」となります。

次の4,5行目が問題ですよね。

set hensu=ネコ

echo %hensu%

表示する直前で変数「hensu」に値「ネコ」を入れているのにも関わらず「クマ」と表示されます。

ここが重要なのでもう一度別の言い方で解説をすると

変数の中身はその行、そのコマンドを読み込んだときに値に置き換わるからです。

if “%hensu%” == “クマ” (

    set hensu=ネコ

    echo %hensu%

)

→このコードが一気に処理される

if “%hensu%” == “クマ”

のコードが展開された時点で、条件判定部分とその後のカッコの中にある「%hensu%」は、すべて「クマ」になります。

つまり、該当箇所が読み込まれた時点でecho %hensu%はecho クマとなっているのです

if “%hensu%” == “クマ” (

    set hensu=ネコ

    echo %hensu%

)

if “クマ” == “クマ” (

    set hensu=ネコ

    echo クマ

)

上記の2つのようになります。

このような理由から、コマンドプロンプト画面上には「クマ」と表示されるのです。

echo %hensu%はecho ネコですが、実際にはecho クマ になります。

これを「環境変数の即時展開」といいます。

環境変数の中身が読み込まれた時点、コマンドが処理された自他時点で展開される(値が置き換わる)から「環境変数の即時展開」といいます。

これがバッチファイルにおける変数が値に置き換わる際のキマリです。

しかし、これでは困ったり、うまくいかなかったりする時がありますよね。

コマンドが処理されたときではなく、実際に実行するタイミングで変数に置き換える場合が多いと思います。

そんな時は遅延環境変数を利用します。次節では、遅延環境変数を解説します。

遅延環境変数の使い方

遅延環境変数は変数を設定する前に、バッチファイルの最初の方に

setlocal enabledelayedexpansion

と書きます。

変数の中身を見るときに「%(パーセント)」ではなく「!(エクスクラメーションマーク)」で囲むと、読み込むときではなく実行するときに値に置き換わります。

遅延環境変数の使い方
  • 変数を設定する前、バッチファイルの最初の方で「setlocal enabledelayedexpansion」を記載する
  • 変数を見るときに「%」ではなく、「!」で囲む
  • 遅延環境変数を終わらせるには「endlocal」を記載する

それでは、前節の例をもとに下記のバッチファイルを見てきましょう。

@echo off
setlocal enabledelayedexpansion
set hensu=クマ
if "%hensu%" == "クマ" (
    set hensu=ネコ
    echo !hensu!
)
pause

コマンド処理の結果

実行結果が「ネコ」と表示されましたね。

このように「実行時に変数を値に置き換えること」を「遅延環境変数の展開」と言います。

ちなみに遅延環境変数をやめたい時は「endlocal」と記載すれば、大丈夫です。

試しに下記のコードを展開します。

@echo off
setlocal enabledelayedexpansion
set hensu=クマ
if "%hensu%" == "クマ" (
    set hensu=ネコ
    echo %hensu%
)
endlocal
set hensu=クマ
if "%hensu%" == "クマ" (
    set hensu=ネコ
    echo !hensu!
)
pause

コマンド処理結果はこちら

コマンド処理結果はこちら。

結果は1回目のechoは「ネコ」、2回目のechoは「クマ」となりました。2回目の時は遅延環境変数が終わっているので、クマとなりました。

このように遅延環境変数を設定した後(setlocal enbledelayexpansionで設定した後)、終わらるには「endlocal」と書けば終えることができます。

setlocal enabledelayedexpansionを単語別に和訳すると、下記のとおりなります。

・set…設定をする

・local…局所的な

・enable…有効な

・delay…遅延する、遅れる

・expansion…拡張、展開

これを読み仮名で振ってみると

「設定する 局所的な 有効な 遅延する 展開」

となり、文にすると

「有効な遅延環境を展開を設定する」となります。

和訳すると少しは覚えやすくなりますかね?

以上です。

コメント

タイトルとURLをコピーしました