Board logo

标题: [已解决]批处理命令pushd及popd有何作用? [打印本页]

作者: crist    时间: 2011-4-28 15:13     标题: [已解决]批处理命令pushd及popd有何作用?

情况:
c:\windows\system32\runonce.cmd
  1. if exist %windir%\system32\cwnd.exe cwnd /hide @
  2. start "" "c:\softwares\a.cmd"
复制代码
c:\softwares\a.cmd
  1. start b.exe
  2. DEL %0
复制代码
发现a.cmd提示b.exe不是可运行程序

将a.cmd改成以下代码
  1. pushd %~dp0
  2. start b.exe
  3. del %0
复制代码
补充说明:runonce.cmd运行时不显示cmd窗口,a.cmd运行时显示cmd窗口

问题:发现a.cmd可以运行完b.exe,但是不能退出cmd窗口而是返回了a.cmd所在的目录:
c:\softwares

请问这是怎么回事?

关于3楼的方法(start /b),测试发现没成功
关于11楼的方法(start cmd /c),测试成功。谢谢指教!
作者: batman    时间: 2011-4-28 15:31

因为start命令是另开窗口运行目标目录下的程序,但是还是在当前目录下运行,所以a.cmd中会提示b.exe不是可运行的程序,因为c:\windows\system32下并没有b.exe。当a.cmd中启用pushd命令指定目标目录c:\softwares为当前运行目录时,实际上就是创建了一堆栈,将目标目录c:\softwares推入堆栈,当命令运行结束后,如不用popd及时销毁堆栈,命令行就会停留在堆栈中。
作者: hanyeguxing    时间: 2011-4-28 15:41

本帖最后由 hanyeguxing 于 2011-4-28 19:12 编辑

2# batman


这里 a.cmd 没有退出关闭窗口和 pushd 及 popd 有关系吗?


1# crist


1,为什么提示文件找不到?你在 a.cmd 中加一行 echo %cd% 就明白了。因为依然以父批处理工作目录为当前工作目录。
2,为什么返回到目录而没有退出?你在 a.cmd 中加一行 echo %CMDCMDLINE% ,他是用 cmd /k 启动的。
3,同时,运行完 del %0 也会报错,原因同上。为什么其他批处理使用 del %0 不会报错?因为他们是由 cmd /c 启动的
如果想用 start 、还想让他运行完关闭、还想让 del %0 不报错,则:
c:\windows\system32\runonce.cmd
  1. 2>nul start /b "" "c:\softwares\a.cmd"
复制代码
c:\softwares\a.cmd
  1. @echo off
  2. pushd "%~dp0"
  3. start "" "b.exe"
  4. popd
  5. del %0
复制代码

作者: applba    时间: 2011-4-28 16:05

2# batman


这个类似于数据结构里面堆栈的入栈和出栈把

请可以pushd和popd可以嵌套吗?
作者: hanyeguxing    时间: 2011-4-28 16:06

4# applba


完全可以嵌套
作者: Hello123World    时间: 2011-4-28 18:56

start命令如果不指定路径,就会默认程序是在c:\windows\system32文件夹下,所以a.cmd提示b.exe不是可运行程序。
pushd %~dp0
保存路径命令pushd具有跳转功能,一保存就会跳转到该目录。
作者: qzwqzw    时间: 2011-4-28 19:09

2# batman
pushd是将当前路径推入栈,再将指定路径设为当前路径。
作者: batman    时间: 2011-4-28 19:45

7# qzwqzw
受教,看来非计算机专业在原理上的理解总是不能到位。。。
作者: crist    时间: 2011-4-29 16:28

虽然还是有点不懂,但是大概的意思明白了,谢谢各位热心指教。
作者: crist    时间: 2011-4-29 16:32

3# hanyeguxing


如果a.cmd结尾不用popd,那么runonce.cmd的后续代码是否无法执行?
作者: qzwqzw    时间: 2011-4-29 16:55

不会
start a.cmd启动了新的CMD进程
它与runonce.cmd所在的CMD进程互相独立
不会相互影响

不过因为start a.cmd使用cmd /k调用
导致产生的cmd会话不自动关闭
所以建议改为 start "" cmd /c a.cmd
作者: applba    时间: 2011-4-30 12:15

不管是否隐藏窗口,start开启的cmd.exe总是会产生新的进程实例……
如果你启用了/i,环境变量是可以继承过去的……
作者: caruko    时间: 2011-4-30 12:51

pushd 你可以当做 cd /d,只是保存了更改前的路径。
popd 返回到pushd 命令之前的目录。
作者: applba    时间: 2011-5-14 06:21

试试setlocal




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2