UNC パスに pushd を使用した後、%CD% が機能しないのはなぜですか?

UNC パスに pushd を使用した後、%CD% が機能しないのはなぜですか?

バッチ ファイルで、ファイル内の unc パスのリストを反復処理し、pushd を使用してコンテキストをその場所に変更してから、コマンドを実行しています。%CD% は、現在プッシュされているディレクトリではなく、前のディレクトリの場所を示します。

for /f "tokens=*" %%A in (filesharelist.txt) do (
 pushd %%A
 echo CD=%CD% - expecting x:\ or x:\subpath here, but get previous directory
 REM xcopy *.xml %DestinationDirectory% /V /C /Y /Z
 popd
)

現在のディレクトリを取得するにはどうすればよいですか?

答え1

%CD%期待通りに動作します。問題は、それが拡張されていることです前にループforは実行されます。代わりに遅延展開を使用してください。

setlocal enabledelayedexpansion
for /f "tokens=*" %%A in (filesharelist.txt) do (
 pushd %%A
 echo CD=!CD!
 REM xcopy *.xml %DestinationDirectory% /V /C /Y /Z
 popd
)

変数の展開は、cmd少し直感に反します。通常の環境変数(形式、、など%foo%の疑似変数を含む)は、ステートメントが実行されるときに展開されます。%date%%cd%解析された実行時ではなく、ブロックがdo1つのステートメントとしてカウントされるので、ブロック内のすべての変数はその値に置き換えられます。前にループforも実行されます。つまり、%CD%元の値に置き換えられます前にループ。当然ながら、これが値です前にpushd

遅延展開は、ステートメントが実行される直前に変数を展開することでこの問題を回避します。処刑された!foo!ただし、そのためにはフォームを使用する必要がありますそして明示的にアクティブ化するsetlocal enabledelayedexpansionか、cmd起動するcmd /v:onか、レジストリで有効にする必要があります。最も安全な方法は、外部の構成や環境に依存しないため、最初の方法です。

ボーナスクイズ: どして %DestinationDirectory% まだ意図したとおりに動作しますか?

関連情報