获取当前批处理文件的目录

381

首先,我看到了这个主题,但我无法理解它。

问题:

D:\path\to\file.bat中有一个批处理文件,其内容如下:

echo %cd%
pause

输出结果为:

C:\

必须是D:\path\to

我做错了什么?


11
您应该阅读问题的所有答案,特别是票数较高的答案,而不仅仅是被采纳的答案。在您发布的链接中得分最高的答案已经回答了您的问题。 - dbenham
4
如果您在键入批处理文件名时在c:\中,则% cd%将打印c:\。 - foxidrive
4个回答

635

系统只读变量 %CD% 保存了批处理调用者的路径,而不是批处理文件的位置。

您可以使用 %0 获取批处理脚本本身的名称(例如:scripts\mybatch.bat)。可以对此应用参数扩展,因此%~dp0将返回批处理脚本的驱动器和路径(例如:W:\scripts\),%~f0 将返回完整路径名(例如:W:\scripts\mybatch.cmd)。

您可以使用以下语法来引用与批处理脚本位于同一文件夹中的其他文件:

CALL %0\..\SecondBatch.cmd

这甚至可以用在子程序中,Echo %0将给出调用标签,但是echo "%~nx0"将给你批处理脚本的文件名。

当展开%0变量时,结果被括在引号内。

更多关于批处理参数的信息


1
看,我不需要在 D:\Dir1\Dir2\stm.sql 中运行 stm.sql。我需要 mysql.exe -u root -p mysql < %cd%\stm.sql 来执行那些 stm.sql 命令。 - Hamed Kamrava
@HamedKamrava 这是针对我的 SQL 批处理吗?不是像 *.bat*.sh 那样的批处理文件吗? - Stoleg
@stoleg- 我知道 echo %0 可以显示批处理文件的完整路径,但我需要的是 D:\Dir1\Dir2\ 而不是 D:\Dir1\Dir2\batchfile.bat - Hamed Kamrava
1
系统只读变量%CD%保存调用批处理文件的路径,而不是批处理文件的位置。 - Stoleg
56
echo %~dp0会返回批处理文件所在的路径。echo %~f0会返回包含批处理文件名称的路径。 - Stoleg
显示剩余3条评论

165

非常简单:

setlocal
cd /d %~dp0
File.exe

21
代码很短,但理解起来并不简单。File.exe 是什么?当前目录路径是否存储在 %~dp0 中? - Ivailo Bardarov
5
我只是在批处理文件的第一行使用了 cd /d %~dp0,然后它就起作用了。 - mkb
3
"setlocal"命令会导致任何环境变量的更改,包括当前目录,都将被限制在批处理文件执行期间,直到遇到"endlocal"命令或者批处理文件结束时才会被取消。如果你想要更改环境变量或者当前目录,使用"setlocal"是一个好的习惯。 - Jamie
5
最好使用"%~dp0"而不是%~dp0。引号将确保路径被视为一个标记,即使存在空格,还可以防止像&这样的毒害字符。 - dbenham
1
当您在表示路径的变量中使用~时,它允许我们提取路径的特定部分,d表示驱动器,p表示路径,n表示名称,x表示扩展名。例如,假设以下行在c:\temp\myfile.bat中:echo off echo %0 echo %n0 echo %x0 echo %d0 echo %p0 echo on将打印:c:\temp\myfile.bat myfile .bat c: \temp\ - Pramod B R
显示剩余3条评论

46

在您的 .bat 文件中:

set mypath=%cd%

现在您可以使用变量%mypath%来引用.bat文件的文件路径。要验证路径是否正确:

@echo %mypath%
例如,一个名为DIR.bat的文件,其内容如下。
set mypath=%cd%
@echo %mypath%
Pause

从目录g:\test\bat运行,将在DOS命令窗口中打印该路径。


1
这是最好的和最简单的解决方案。 - Nani
28
这不是一个好的解决方案,因为它没有考虑被另一个路径上的另一个文件调用的批处理脚本。 - theQuestionMan
1
当以提升的权限运行时,%cd% 返回的是 C:\Windows\system32 而不是它所存储的目录。 - PravyNandas
2
另外,你可以直接使用%cd%,无需先复制它。 - Rick

17

这是我在所有批处理文件的顶部使用的内容。 我只需从我的模板文件夹中复制/粘贴即可。

@echo off
:: --HAS ENDING BACKSLASH
set batdir=%~dp0
:: --MISSING ENDING BACKSLASH
:: set batdir=%CD%
pushd "%batdir%"
将当前批处理文件的路径设置为%batdir%,可以在当前批处理文件中的后续语句中调用它,而不管此批处理文件更改到何处。 使用PUSHD允许您使用POPD快速将此批处理文件的路径设置为原始%batdir%。 请记住,如果使用%batdir%ExtraDir或%batdir%\ ExtraDir(取决于上面使用的版本,是否以反斜杠结尾),则如果路径包含空格,则需要将整个字符串括在双引号中(即“%batdir%ExtraDir”)。 您始终可以使用PUSHD%〜dp0。 [https://ss64.com/nt/syntax-args.html]有关(%〜)参数的更多信息。

请注意,在行首使用(::)将其变成注释行。 更重要的是,使用::允许您在该注释中包含重定向器、管道、特殊字符(即<>&|等)。

:: ORIG STMT WAS: dir *.* | find /v "1917" > outfile.txt
当然,PowerShell可以做到这些,而且还能做更多。

4
非常好的回答,非常感谢! :-) 请注意您的第二种技术(set batdir=%CD%)。这是不正确的,因为它是调用者的路径,而不是批处理文件本身的路径。获取正在执行的批处理文件路径的唯一有效方式是 %~dp0 - Mitch McMabers

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