Windows批处理变量扩展无法正常工作。

3

当我将%0的驱动器号存储到变量中时,我遇到了一些意外的输出。

以下代码片段从C:\Temp\Test运行:

@echo off
for %%I in ("%~0") do set "Target=%%~dI"
echo Target:  %Target%
pushd %Target% && echo Current: %CD% || echo Failed to change dir!

这条命令可以输出正确的目标的值,但是不能输出当前目录的值:

Target:  C:
Current: C:\Temp\Test

预期输出:

Target:  C:
Current: C:\

我也尝试了使用延迟扩展相同的代码,但这也没有起作用。有人可以解释一下这是怎么回事吗?

3个回答

4

你的问题与变量扩展无关,而与pushd的行为有关。

这个场景可以解释pushd(或者顺便提一下cd)是如何工作的。

C:\>cd temp
C:\temp>_

现在%cd%c:\temp。如果你“移动”到另一个驱动器

C:\temp>e:

并尝试

E:\>pushd c:
C:\temp>_

现在你可以看到,%cd%已经回到了C:\temp,而不是你预期的C:\

但是...

C:\temp>e:
E:\>pushd c:\
C:\>_

%cd%转换成你期望的路径C:\。因此,你的批处理文件可以简单地写成:
pushd %~d0\

+1,刚刚意识到自己也一样 :-),但输出仍有缺陷。 - jeb
pushd %dp0 中的尾随反斜杠是关键,谢谢! :) - Andreas
是的,我指的是“缺失的尾部反斜杠”。 - Andreas

1

为什么你期望看到Current: C:\
你从C:\Temp\Test运行脚本。
所以%CD%扩展到C:\Temp\Test是正确的。

如果你期望%CD%随着PUSHD %target%的使用而改变,你需要拆分该行或者对!CD!使用延迟扩展,因为在执行PUSHD之前,会先解析整行并进行百分号扩展。

另一个问题是pushd C:不会更改路径,因为C:是相对路径,你需要使用C:\

@echo off
set "Target=%~d0\"
setlocal EnableDelayedExpansion
echo Target:  %Target%
pushd %Target% && echo Current: !CD! || echo Failed to change dir^^!

set /? 表示 %CD% 展开为当前目录名。pushd /? 表示它将切换到给定的目录。所以我认为我的期望是合理的。你建议的代码给了我与我的输出完全相同的结果(在Win XP上)。 - Andreas

0

我无法解释这种行为,但你可以使用以下方法模仿它:

pushd %Target%
if %ERRORLEVEL%==0 (echo Current: %CD%) else (echo Failed to change dir!)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接