在Windows批处理文件中,%~d0是什么意思?

414

我正在查看一个批处理文件,其中定义了以下变量:

set _SCRIPT_DRIVE=%~d0
set _SCRIPT_PATH=%~p0
  • %~d0%~p0实际上是什么意思?
  • 是否有一组众所周知的值,例如当前目录、驱动器、脚本参数等?
  • 还有其他类似的快捷方式可以使用吗?

还在这个答案中详细描述:https://dev59.com/KG445IYBdhLWcg3wGmk6#5034119 - Cadoiz
9个回答

623
魔术变量%n包含用于调用文件的参数:%0是bat文件本身的路径,%1是之后的第一个参数,%2是第二个参数,以此类推。

由于这些参数通常是文件路径,因此有一些额外的语法来提取路径的部分。 ~d是驱动器,~p是路径(不包括驱动器),~n是文件名。它们可以组合使用,所以~dp是驱动器+路径。

因此,在bat中%~dp0非常有用:它是执行bat文件所在的文件夹。

您还可以获取关于文件的其他种类的元信息:~t是时间戳,~z是大小。

请参阅此处了解所有命令行命令的参考。波浪线魔法代码在for下有描述。


32
提醒自己:echo %~dp0 只能在批处理文件中使用,无法在命令行中使用。傻瓜! - northben
2
%~d0%~d0% 之间有什么区别吗? - Geoffrey
3
@Pacerier: %0 是包括脚本文件名在内的完整路径。%~dp0 是指脚本所在文件夹的路径,但不包括脚本文件名。 - JacquesB
4
自己的笔记:echo %~pd0echo %~dp0 的输出相同(与期望的相反)。此外,%0 的值取决于是双击批处理文件还是从命令行运行。 - Pacerier

176

它们是增强型变量替换。它们修改批处理文件中使用的%N变量。如果你喜欢在Windows中进行批处理编程,它们非常有用。

%~I         - expands %I removing any surrounding quotes ("")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

通过运行FOR /?,您可以找到上述内容。


这份在线文档非常令人困惑。我从未遇到过一个程序员知道要在for /?文档中查找关于在for循环之外使用的变量的文档!此外,对我和许多其他人来说,"expands %I"的含义并不清楚,即“您可以用0替换I”。尽管如此,这个答案仍然有用,可以向其他人解释原始文档的位置。 - kevinarpe

55

是的,你还可以使用其他快捷键,下面列出了一些。在您的命令中,“~d0”表示第0个参数的驱动器号。

~ expands the given variable
d gets the drive letter only
0 is the argument you are referencing

因为第0个参数是脚本路径,所以它可以帮你获取路径的驱动器字母。你也可以使用以下快捷方式。

%~1         - expands %1 removing any surrounding quotes (")
%~f1        - expands %1 to a fully qualified path name
%~d1        - expands %1 to a drive letter only
%~p1        - expands %1 to a path only
%~n1        - expands %1 to a file name only
%~x1        - expands %1 to a file extension only
%~s1        - expanded path contains short names only
%~a1        - expands %1 to file attributes
%~t1        - expands %1 to date/time of file
%~z1        - expands %1 to size of file
%~$PATH:1   - searches the directories listed in the PATH
               environment variable and expands %1 to the fully
               qualified name of the first one found.  If the
               environment variable name is not defined or the
               file is not found by the search, then this
               modifier expands to the empty string    

%~dp1       - expands %1 to a drive letter and path only
%~nx1       - expands %1 to a file name and extension only
%~dp$PATH:1 - searches the directories listed in the PATH
               environment variable for %1 and expands to the
               drive letter and path of the first one found.
%~ftza1     - expands %1 to a DIR like output line

当你运行CALL /?或FOR /?命令时,这也可以在命令提示符中直接找到。


13

好的链接和[成语]相关的信息,还解释了`%s0`,即完整的脚本名称。 - Laurie Stearn

11

另一个非常有用的提示是,要将当前目录设置为不同的驱动器,需要先使用%~d0,然后再使用cd %~dp0。这将更改目录到批处理文件所在的驱动器,然后转到其文件夹。

对于# oneLinerLovers(一行命令爱好者),cd /d %~dp0将同时更改驱动器和目录:)

希望这可以帮助某些人。


8
另一个选项是pushd %~dp0,它可以更改当前驱动器而不会出现问题,并且还可以让您稍后使用popd返回到原始驱动器/路径。 - bcrist

9

需要注意的一些问题:

如果你双击批处理文件,%0会被引号包围。例如,如果你将该文件保存为c:\test.bat

@echo %0
@pause

双击它会打开一个带输出的新命令提示符窗口:
"C:\test.bat"

但是如果您首先打开命令提示符并直接从该命令提示符调用它,%0 将引用您所输入的任何内容。如果您键入 test.batEnter,则 %0 的输出将没有引号,因为您没有输入引号:

c:\>test.bat
test.bat

如果您输入testEnter,则%0的输出也将没有扩展名,因为您没有输入扩展名:
c:\>test
test

同样适用于tEsTEnter

c:\>tEsT
tEsT

如果您输入"test"Enter,则%0的输出将带有引号(因为您键入了它们),但没有扩展名:

c:\>"test"
"test"

最后,如果你输入"C:\test.bat",输出结果与双击文件一模一样:
c:\>"C:\test.bat"
"C:\test.bat"

请注意,%0不是所有可能的值,因为您可以从其他文件夹调用脚本。
c:\some_folder>/../teST.bAt
/../teST.bAt

以上展示的所有示例也会影响%~0,因为%~0的输出仅是%0的输出减去引号(如果有的话)。


7

%~d0会返回参数0(即脚本名称)的驱动器字母,%~p0会返回路径。


3

这段代码解释了波浪符号的使用,这对我来说是最令人困惑的事情。一旦理解了这一点,就会使事情变得更容易理解:

@ECHO off
SET "PATH=%~dp0;%PATH%"
ECHO %PATH%
ECHO.
CALL :testargs "these are days" "when the brave endure"
GOTO :pauseit
:testargs
SET ARGS=%~1;%~2;%1;%2
ECHO %ARGS%
ECHO.
exit /B 0
:pauseit
pause

所以波浪号使它们成为引用字符串? - Gary Carlyle Cook

0

它显示了您当前所在的文件或目录的当前位置。例如,如果您的批处理文件位于桌面目录中,则“%〜dp0”将显示桌面目录。如果您希望它显示当前目录和当前文件名,您可以键入“%〜dp0%〜n0%〜x0”。


1
"%~dpnx0" 会更好。 - FrinkTheBrave

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