批处理中%cd%与%~dp0的区别

博客原文链接

欢迎来我的博客:http://jerkwisdom.github.io/developing/system/dos-current-path/

问题描述

假设我们要在批处理a.bat里调用执行批处理b.bat,b.bat需要知道b.bat的当前位置,并执行run.exe,如下:

// directory structure
// c:
// -a.bat
// -program
//        -b.bat
//        -run.exe

// a.bat
call "%cd%\program\b.bat"

// b.bat
"%cd%\run.exe"

那么现在能不能成功执行run.exe呢?

问题分析

%cd%和%~dp0都能用来表示当前目录,但是他们在不同的使用场景下,功能却不相同:

  • %cd%代表的是当前工作目录(current working directory),为变量;
  • %~dp0代表的是当前批处理文件所在完整目录(the batch file's directory),为常量。

我们来看看下面的例子:

// directory structure
// c:
// -c.bat
// -program
//        -d.bat

// c.bat
call "%cd%\program\d.bat"

// d.bat
@echo off
echo cd = %cd%
echo dp0 = %~dp0

直接运行d.bat,结果为

cd = C:\program
dp0 = C:\program\

直接运行c.bat,结果为

cd = C:\
dp0 = C:\program\

从上面的结果可以看出:

  • 执行d.bat时,当前工作目录为d.bat所在目录;
  • 执行c.bat时,当前工作目录为c.bat所在目录,即使在调用d.bat后,该工作目录依旧是c.bat所在目录。

问题解决

让我们再来看看问题描述中提及的问题——能不能成功执行run.exe呢?

答案是:不能。“%cd%\run.exe”表示的是“C:\run.exe”,并非“C:\program\run.exe”。那么如何更改呢?有两种方案:

// plan A
//  change the current working directory

// a.bat
cd "%~dp0"
call "%cd%\program\b.bat"

// b.bat
cd "%~dp0"
"%cd%\run.exe"

// plan B
//  using %~dp0 directly

// a.bat
call "%~dp0program\b.bat"

// b.bat
"%~dp0run.exe"

问题延伸

上面的解决方案中plan A通过更改当前目录来解决该问题,可以这里面也存在另外一个问题,让我们看下面的例子:

// directory structure
// c:
// -program
//        -f.bat
// d:
// -e.bat

// plan A
//  change the current working directory

// e.bat
cd "%~dp0"
call "c:\program\f.bat"

// f.bat
cd "%~dp0"
"%cd%\run.exe"

现在e.bat和f.bat不在同一个盘符了,从e.bat切换当前工作目录到f.bat直接使用cd是不行的,必须要使用:

cd /d "%~dp0"

这个地方容易疏忽,切记不要犯错

问题总结

我们来重申下%dp0和%cd%的区别,%cd%和%dp0都能用来表示当前目录,但是他们在不同的使用场景下,功能却不相同:

  • %cd%代表的是当前工作目录(current working directory,variable);
  • %~dp0代表的是当前批处理文件所在完整目录(the batch file's directory,fixed)。

从目前我们的使用情况来看,尽量使用%~dp0,不建议使用%cd%,有其他需求除外。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 个人学习批处理的初衷来源于实际工作;在某个迭代版本有个BS(安卓手游模拟器)大需求,从而在测试过程中就重复涉及到...
    Luckykailiu阅读 4,779评论 0 11
  • dos 批处理 一:windows的命令行模式(win+R)在里面写CMD就可以进入windows的命令行模式了二...
    chenchao981阅读 779评论 0 6
  • 说明本次redis集群安装在rhel6.8 64位机器上,redis版本为3.2.8,redis的gem文件版本为...
    读或写阅读 15,206评论 3 9
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,967评论 19 139
  • 170320 小组讨论,写的草稿让大家还算满意,稍微安心了许多。 很久没去上语言课,还有一周就要结束了。再次去的时...
    XxXxXxN阅读 138评论 0 0