実際には、SETLOCAL(help setlocal
またはsetlocal /?
)のヘルプドキュメントがかなりうまく説明されています。明白でない唯一のことは、環境変数を含むだけでなく、現在のディレクトリ、ECHO状態、および遅延拡張および拡張状態も含むことであることは明らかである。もっとあるかもしれませんが、私はそれを今のところ考えることができません。
あなたをトリップされるものは、実際にかなりよく説明されている:「バッチスクリプトの終わりに達すると、暗黙のENDLOCALが、そのバッチスクリプトによって発行された未処理のSETLOCALコマンドのために実行される。」ではありません呼び出されたサブルーチンでも同じことが言えます。
バッチスクリプトが終了すると、暗黙のENDLOCALによってCHDIRの効果が「消去」されます。 2番目のコードの明示的なENDLOCALはルート環境に戻ってくるので、CHDIRは保存されます。
更新
カレントディレクトリは、通常%CD%
を使用して現在の値を取得することができていても、環境変数ではありません。 SET CD
を使って証明することができます。おそらく、 "環境変数CDが定義されていません"ということになります。 set "CD=some value"
を使用して独自の真のCD変数を明示的に定義すると、%CD%
は現在のディレクトリではなく、割り当てた値を返します。
元のSETLOCALコマンドは、古いCOMMAND.COMの日に遅延拡張または拡張を戻すことはありませんでした。 Enable/Disable DelayedExpansionとEnable/Disable Extensionsオプションは、CMD.EXEが導入されたときに追加されました。これは、MSがどのように機能を実装することを決めたかです。そうである必要はありませんでした。多くの点で、SETLOCAL/ENDLOCALを使わずにこれらの状態を制御できないことは残念です。私はしばしば、環境をローカライズせずに遅延拡張を有効または無効にできることを望みます。
2つの重要な点があります。現在のディレクトリは環境変数で、スクリプトの最後に暗黙のENDLOCALがあり、元の環境を返します。今、私はsetlocalをよく理解することができます。なぜ、拡張された拡張がsetlocalで行われなければならないのか、それほど明確ではありません。それは別の質問ですが、なぜ私が失われたのかを説明しています.setlocalでの私の経験は、変数の評価方法を変更するために使用され、リンクが表示されないということでした。 –
@ Dominic108 - 最新の回答をご覧ください。 – dbenham
良い更新。私は現在のディレクトリ%__ CD __%がSETで変更できるとは考えていませんでしたが、それは環境の一部である変数だけです。 –