Programming Field

DOS コマンド一覧

Setlocal

[Windows NT/2000/XP 以降] 環境変数の設定とカレントディレクトリをバッチファイル内のみに留めるようにします(環境のローカル化)。

構文

setlocal [enableextensions | disableextensions] [enabledelayedexpansion | disabledelayedexpansion]
enableextensions | disableextensions
[拡張機能] どちらかを指定した場合、次のEndlocalが呼び出されるまでコマンド拡張機能を有効または無効にします。「enableextensions」を指定すると有効に、「disableextensions」を指定すると無効にします。この設定はCmdで拡張機能を無効にしていても使用できます。
enabledelayedexpansion | disabledelayedexpansion
[Windows 2000 以降] [拡張機能] どちらかを指定した場合、次のEndlocalが呼び出されるまで環境変数の遅延展開機能を有効または無効にします。「enabledelayedexpansion」を指定すると有効に、「disabledelayedexpansion」を指定すると無効にします。詳しくは「!」の説明をご覧ください。
(引数なし)
上記の引数をいずれも指定しない場合、環境のローカル化のみを行います。(引数を指定した場合もローカル化を行います。)

[Windows XP 以降] [拡張機能] 上記の引数を指定した場合、SetlocalはErrorlevelを設定します。コマンドに成功した場合は「0」、引数が間違っているなどで失敗した場合は「1」を設定します。enabledelayedexpansion/disabledelayedexpansionの場合、拡張機能が無効である場合はErrorlevelを設定(変更)しません。

※ Setlocalは拡張機能が有効かどうかにかかわらず、また引数の有無にかかわらず、前述の通りErrorlevelを設定します。(Windows 7・Windows 10 [Build 10586] で確認)

なお、「enableextensions または disableextensions」と「enabledelayedexpansion または disabledelayedexpansion」はいずれか一方を同時に指定することができます。例えば「setlocal disableextensions enabledelayedexpansion」という記述は有効であり、「setlocal」の効果に加え「disableextensions」と「enabledelayedexpansion」の効果も適用します。

解説

次のEndlocalコマンドが呼び出されるまでの間で有効な環境変数を定義したりカレントディレクトリを変更したりする際に使います。Setlocalを呼び出すと、その後Setなどを使って環境変数が変更されたりChdir/Pushdでカレントディレクトリが変更されたりしても、Endlocalを呼び出すことで変更される前の状態に戻すことができます。(ただしPushdについては厳密には元に戻りません。詳しくはPushdのページをご覧ください。)

また、Endlocalが存在しない場合はそのバッチプログラム内で有効となり、バッチプログラムを抜けるとEndlocalが呼び出されたのと同じようにSetlocalが呼び出される前の状態に戻ります。

なお、Setlocalは複数回呼び出すことができ、その都度ローカル化が実施されます。これを終えるには、対応する回数だけEndlocalを呼び出す必要があります。(いわゆるネスト化)

[拡張機能] Setlocalにそれぞれの引数を指定することで、一時的に拡張機能を有効・無効にしたり環境変数の遅延展開機能を有効・無効にしたりすることができます。これらの変更も次のEndlocal呼び出しで元に戻ります。また、引数を伴っている場合は従来のSetlocalの機能(環境変数のローカル化)は実行されません → 引数を伴っている場合でも従来のSetlocalの機能は実行され、Endlocalによって引数による挙動の切り替えの終了と環境のローカル化の終了がなされます(2016/05/08 修正)。さらに、引数を伴っている場合Setlocalは終了コードを設定します(伴っていない場合は設定や変更をしません)。

なお、コマンドのヘルプを読むと「拡張機能を有効にしないと enabledelayedexpansion / disabledelayedexpansion が利用できない」ように捉えることができますが、実際には拡張機能が無効になってもこの引数による設定変更は適用されるようです(Windows 7での確認)。 → 拡張機能が無効のプロンプトでバッチファイルが実行された場合、そのバッチファイル内で事前に「setlocal enableextensions」が必要です。(ただし、少なくとも Windows 7 では「setlocal enableextensions」なしに「setlocal enabledelayedexpansion」の実行が可能です。)

サンプル1 (バッチファイル)
setlocal
set PATH=N:\bin;%PATH%
hoge.exe
endlocal
foo.exe

いったん環境のローカル化を行った後PATHに「N:\bin」を追加し、その上で「hoge.exe」を実行します。その後Endlocalで元に戻した後に「foo.exe」を実行しています。この場合、「hoge.exe」の実行時にはPATHに「N:\bin」が含まれており、「foo.exe」の実行時には「N:\bin」は含まれなくなります。

サンプル2 (バッチファイル)
setlocal enableextensions
cd /d "%~dp0"
execute.exe

拡張機能を有効化、かつ環境のローカル化を行った上でカレントディレクトリをバッチファイルのあるディレクトリに変更し、「execute.exe」を実行します。これにより「execute.exe」はバッチファイルのあるディレクトリをカレントディレクトリとして実行しますが、バッチファイル終了時にはカレントディレクトリが元に戻ります。また、「cd /d」および「%~dp0」は拡張構文であるため、Setlocalに「enableextensions」を指定して拡張機能を有効化する必要があります。

なお、拡張機能を有効化できるかどうかを判定する例は次のサンプルをご覧ください。

サンプル3 (バッチファイル)
find "invalid" 9:\invalid 2> NUL
setlocal enableextensions
if errorlevel 1 goto no_extensions

bar.exe
if "%ERRORLEVEL%"=="0" echo Succeeded. else echo Failed.
goto last

:no_extensions
echo Cannot run this program.

:last

拡張機能を有効にしたうえで「bar.exe」を実行し、その後プログラムの終了コードをチェックするプログラムです。Errorlevelを環境変数として扱う場合は拡張機能が有効になっている必要があるため、確実な評価を行うためSetlocalを呼び出しています。

なお、最初の3行ではFindを無効な引数で呼び出してわざとErrorlevelを0以外の値に設定し、その状態でSetlocalを呼び出しています。このようにすることで、Setlocalの引数が利用できない環境ではErrorlevelが書き換わらない(利用できてコマンドが成功する場合0になる)ことを利用して、正しく拡張機能を有効にできたかどうか判定することができます。

※ コマンドのヘルプではVerifyコマンドが使われていますが、Verifyコマンドは終了コードを設定しないようです。