转载:https://www.jb51.net/article/105325.htm

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

 
 
Windows下批处理中%cd%和%~dp0都能用来表示当前目录,但是他们在不同的使用场景下,功能却不相同。下面这篇文章就来给大家详细介绍了DOS批处理中%cd%与%~dp0的区别,需要的朋友可以参考借鉴。
 
问题描述

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

1
2
3
4
5
6
7
8
9
10
// directory structure
// c:
// -a.bat
// -program
//  -b.bat
//  -run.exe
// a.bat
call "%cd%\program\b.bat"
// b.bat
"%cd%\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,variable);
  • %~dp0代表的是当前批处理文件所在完整目录(the batch file's directory,fixed)。

我们来看看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
// 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
// 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,结果为

1
2
cd = C:\program
dp0 = C:\program\
cd = C:\program
dp0 = C:\program\

直接运行c.bat,结果为

1
2
cd = C:\
dp0 = C:\program\
cd = C:\
dp0 = C:\program\

从上面的结果可以看出:

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

问题解决

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

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

有两种方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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
// 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通过更改当前目录来解决该问题,可以这里面也存在另外一个问题,让我们看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 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"
// 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.batf.bat不在同一个盘符了,从e.bat切换当前工作目录到f.bat直接使用cd是不行的,必须要使用:

1
cd /d "%~dp0"
cd /d "%~dp0"

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

问题总结

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

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

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

DOS批处理中%cd%与%~dp0的区别详解的更多相关文章

  1. DOS批处理中%cd%和%~dp0的区别

    DOS批处理中%cd%和%~dp0的区别   在DOS的批处理中,有时候需要知道当前的路径. 在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0.       这两个变量 ...

  2. DOS批处理中%cd%和%~dp0的区别[forward]

    DOS批处理中%cd%和%~dp0的区别   在DOS的批处理中,有时候需要知道当前的路径. 在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0.      这两个变量的 ...

  3. dos 批处理中%cd% 和%~dp0%的区别

    看网上介绍区别,写的好复杂,其实很简单: %cd%  在批处理和命令窗口都能使用.用于打印,当前工作路径. %~dp0% 则只能用于批处理中,用于获得当前批处理文件所在的路径. 做个试验试一下: @e ...

  4. DOS批处理中%cd%和%~dp0的异同分析

    在DOS的批处理中,有时候需要知道当前的路径.在DOS中,有两个环境变量可以跟当前路径有关,一个是%cd%, 一个是%~dp0. 这两个变量的用法和代表的内容是不同的. 1. %cd% 可以用在批处理 ...

  5. 基于python中staticmethod和classmethod的区别(详解)

    例子 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 class A(object):   def foo(self,x):     print "executing foo ...

  6. C#中struct和class的区别详解

    本文详细分析了C#中struct和class的区别,对于C#初学者来说是有必要加以了解并掌握的. 简单来说,struct是值类型,创建一个struct类型的实例被分配在栈上.class是引用类型,创建 ...

  7. C#中struct和class的区别详解 (转载)

    本文详细分析了C#中struct和class的区别,对于C#初学者来说是有必要加以了解并掌握的. 简单来说,struct是值类型,创建一个struct类型的实例被分配在栈上.class是引用类型,创建 ...

  8. Java中的==和equals的区别详解

    1.基础知识 (1)String x = "hello"; (2)String x = new String ("hello"); 第1种方式的工作机制是,首先 ...

  9. C#中struct与class的区别详解

    转自:http://blog.csdn.net/justlovepro/archive/2007/11/02/1863734.aspx 有这么几点不同: 1.struct 是值类型,class是对象类 ...

随机推荐

  1. 【Go语言入门系列】(八)Go语言是不是面向对象语言?

    [Go语言入门系列]前面的文章: [Go语言入门系列](五)指针和结构体的使用 [Go语言入门系列](六)再探函数 [Go语言入门系列](七)如何使用Go的方法? 1. Go是面向对象的语言吗? 在[ ...

  2. Cython编译独立的可执行文件

    cython --embed -o hello.c hello.pygcc hello.c -o hello -I /Library/Frameworks/Python.framework/Versi ...

  3. 如何使用Xdebug单步调试PHP游戏服务器

    参考文章:https://www.sourcetoad.com/resources/debugging-php-save-time-with-xdebugs-remote-autostart/ 配置参 ...

  4. Johnson全源最短路

    例题:P5905 [模板]Johnson 全源最短路 首先考虑求全源最短路的几种方法: Floyd:时间复杂度\(O(n^3)\),可以处理负权边,但不能处理负环,而且速度很慢. Bellman-Fo ...

  5. Kubernetes K8S在IPVS代理模式下Service服务的ClusterIP类型访问失败处理

    Kubernetes K8S使用IPVS代理模式,当Service的类型为ClusterIP时,如何处理访问service却不能访问后端pod的情况. 背景现象 Kubernetes K8S使用IPV ...

  6. Mybatis----Mapper配置文件

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  7. node.js之koa安装

    默认安装了node 1.cmd中工作目录下输入npm init:一路回车即可: 2.还是在此目录下输入npm i koa:我这里是安装的淘宝镜像即是输入cpm i koa. 3.打开编辑器在文件目录下 ...

  8. [SqlServer]数据库备份-问题及解决

    正常数据库备份 备份:右键要备份的数据库-任务-备份 还原:右键数据库-还原数据库 问题1-"还原数据库备份时报错"介质集有2个介质簇,但只提供了1个.必须提供所有成员" ...

  9. sql.表值类型

    表值类型是在sql server 2008中新加入的功能,我个人觉得确实很有用,之前从没用过,自从来到现在的公司后学到很多东西,所以和大家分享一下. ------建表值类型语法------------ ...

  10. 【LeetCode/LintCode】丨Google面试题:N皇后问题

    n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击(任意两个皇后不能位于同一行,同一列,同一斜线). 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案包含一个明确的 ...