为什么以下 %~d0 返回批处理文件的驱动器号 S 失败:当 CALL 引用批处理文件的名称时?
S:\!DJ DAP>type test.bat
R:
%~d0
S:\!DJ DAP>call test.bat
S:\!DJ DAP>R:
R:\>S:
S:\!DJ DAP>call "test.bat"
S:\!DJ DAP>R:
R:\>R:
R:\>
编辑以下 Jerry 和 MC 的回复:这是一个非 CALL 示例,显示相同:
R:\>s:
S:\!DJ DAP>type test.bat
R:
%~d0
S:\!DJ DAP>test.bat
S:\!DJ DAP>R:
R:\>S:
S:\!DJ DAP>"test.bat"
S:\!DJ DAP>R:
R:\>R:
R:\>
最佳答案
编辑 - npocmaka,你是对的。奇怪的。
原始答案已删除 - 我错了。
但问题不是call
命令。问题是引号和 cmd。
经过测试,在文件名的处理方式以及 cmd 如何处理 api 调用中的一些错误方面,它似乎更像是一个错误/功能。
使用以下批处理文件(test.cmd)
@echo off
setlocal enableextensions
echo Calling subroutine from drive d:
call :getInfo
echo.
c:
echo Calling subroutine from drive c:
call :getInfo
echo.
echo Getting data directly without subroutine
:getInfo
echo ---------------------------------------------------------
echo cd : %cd%
echo d0 : %~d0
echo dp0 : %~dp0
echo f0 : %~f0
echo ---------------------------------------------------------
echo.
goto :EOF
放在d:\temp\testCMD,c盘当前目录为C:\Users,执行结果为:
1.- 不带引号的调用 从 cmd 目录:
test.cmd
Calling subroutine from drive d:
---------------------------------------------------------
cd : D:\temp\testCMD
d0 : D:
dp0 : D:\temp\testCMD\
f0 : D:\temp\testCMD\test.cmd
---------------------------------------------------------
Calling subroutine from drive c:
---------------------------------------------------------
cd : C:\Users
d0 : D:
dp0 : D:\temp\testCMD\
f0 : D:\temp\testCMD\test.cmd
---------------------------------------------------------
Getting data directly without subroutine
---------------------------------------------------------
cd : C:\Users
d0 : D:
dp0 : D:\temp\testCMD\
f0 : D:\temp\testCMD\test.cmd
---------------------------------------------------------
结果:一切正常。
2.- 用引号调用 从 cmd 目录
"test.cmd"
(不,不需要 call
命令)Calling subroutine from drive d:
---------------------------------------------------------
cd : D:\temp\testCMD
d0 : D:
dp0 : D:\temp\testCMD\
f0 : D:\temp\testCMD\test.cmd
---------------------------------------------------------
Calling subroutine from drive c:
---------------------------------------------------------
cd : C:\Users
d0 : D:
dp0 : D:\temp\testCMD\
f0 : D:\temp\testCMD\test.cmd
---------------------------------------------------------
Getting data directly without subroutine
---------------------------------------------------------
cd : C:\Users
d0 : C:
dp0 : C:\Users\
f0 : C:\Users\test.cmd
---------------------------------------------------------
结果:仅当直接从 cmd 的主执行行获取时,才无法获取正确的 %~d0 值。与子程序调用相同,按预期工作。
没有引号测试的所有场景都可以正常工作。使用引号,如果调用行包含驱动器 (ej:
"d:.\test.cmd"
),则所有值都将被正确检索。如果驱动器不包含在批处理调用中,(ej:"test.cmd"
路径中包含批处理目录,或来自 D: 根目录的 "\temp\testCMD\test.cmd"
),检索到不正确的值,但仅来自批处理文件中的主执行行。子程序总是得到正确的值。为什么?不知道。但是当使用 procmon 跟踪 cmd 执行时,在失败的情况下,当 cmd.exe 尝试检索文件的信息时,会为
C:\Users\test.cmd
调用 QueryDirectory API。回答为 NO SUCH FILE
, 但是cmd忽略它并继续执行,显示错误的值 .所以,没有答案,对不起。但我必须“记录”这一点。房间里有什么大师?
更新 : 更多信息here
关于batch-file - CMD: 当 CALL 引用批处理文件的名称时 %~d0 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19781569/