在 BAT 文件中展开“%~dp0”后出现意外的重复目录名

Vla*_*kov 7 windows command-line environment-variables whitespace batch-file

我使用的是 Windows 10 Enterprise x64。我有以下目录层次结构,最内层有一个 BAT 文件:

C:\
  dir\
    my files\
      run.bat
Run Code Online (Sandbox Code Playgroud)

BAT 文件包含以下几行:

@pushd %~dp0
@echo %~dp0
@popd
Run Code Online (Sandbox Code Playgroud)

%~dp0帮助主题for /?本答案中解释了 的含义和用法)

如果我从当前目录为 的命令提示符运行 BAT 文件C:\dir\my files,那么我会得到一个非常合理的结果:

C:\dir\my files>run.bat
C:\dir\my files\
Run Code Online (Sandbox Code Playgroud)

但是如果我从父目录调用它C:\dir,我会得到:

C:\dir>"my files"\run.bat
C:\dir\my files\my files"\
Run Code Online (Sandbox Code Playgroud)

嗯?请注意,最里面的目录名称是重复的,并且"\末尾有一些杂散字符。让我们以不同的方式尝试一下:

C:\dir>"my files\run.bat"
C:\dir\my files\my files\
Run Code Online (Sandbox Code Playgroud)

杂散字符消失了,但目录名称仍然重复。对此有何解释?如何修改 BAT 文件,以便无论从哪个目录调用它都提供相同的输出?

当然,我的真实场景比这个简化版还要复杂。的值%~dp0与其他字符串连接,分配给环境变量,作为参数传递给其他脚本等。

dbe*_*ham 5

这是cmd.exe 中的一个已知错误/设计缺陷-%~dp0如果引用批处理脚本的路径,变体可能会给出错误的结果。

有一个解决方法。您可以可靠地从 CALLed 子例程中获取值(请注意,必须使用至少一个修饰符~d~f例如 等,否则您将获得子例程:label

@echo off
setlocal
pushd %~dp0
echo From main fails: "%~dp0"
call :test
popd
exit /b

:test
echo From subroutine OK: "%~dp0"
Run Code Online (Sandbox Code Playgroud)

-- 样本输出 --

d:\dir>"my files\test.bat"
From main fails: "d:\dir\my files\my files\"
From subroutine OK: "d:\dir\my files\"
Run Code Online (Sandbox Code Playgroud)