em um arquivo em lote, estou percorrendo uma lista de caminhos unc em um arquivo, usando pushd para alterar o contexto para esse local e, em seguida, executando um comando. %CD% fornece a localização do diretório anterior, não o diretório atualmente enviado.
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
)
Como obtenho o diretório atual?
Responder1
%CD%
funciona como deveria. Seu problema é que ele é expandidoantesseu for
loop ainda é executado. Use a expansão atrasada:
setlocal enabledelayedexpansion
for /f "tokens=*" %%A in (filesharelist.txt) do (
pushd %%A
echo CD=!CD!
REM xcopy *.xml %DestinationDirectory% /V /C /Y /Z
popd
)
A expansão variável cmd
é um pouco contra-intuitiva. Variáveis de ambiente normais (no %foo%
formato, incluindo pseudovariáveis como %date%
, %cd%
, ...) são expandidas quando uma instrução éanalisado, não quando é executado. Blocos como o seguinte do
contam como uma única instrução para que cada variável no bloco seja substituída por seu valoranteso for
loop ainda é executado. O que significa %CD%
é substituído pelo valor que tinhaanteso laço. Sem surpresa, este é o valoranteso pushd
.
A expansão atrasada contorna o problema expandindo variáveis logo antes de uma declaração serexecutado. Eles precisam usar o !foo!
formulário para isso, emboraeele deve ser explicitamente ativado setlocal enabledelayedexpansion
ou cmd
iniciado cmd /v:on
ou deve ser ativado no registro. A forma mais segura é a primeira porque não depende de nenhuma configuração ou ambiente externo.
Questionário bônus: Porque %DestinationDirectory%
ainda funciona como pretendido?