Board logo

标题: [其他] 【已解决】请教如何在 for 中使用含空格的路径 [打印本页]

作者: xahstar    时间: 2010-7-9 10:24     标题: 【已解决】请教如何在 for 中使用含空格的路径

  1. for /f "delims=" %%i in ('"c:\test\a a\a.exe"^|"c:\test\b b\b.exe"') do (
  2. echo ok
  3. )
复制代码
出错提示:
'c:\test\a' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
  1. for /f "delims=" %%i in ('c":\test\a a\a.exe"^|"c:\test\b b\b.exe"') do (
  2. echo ok
  3. )
复制代码
输出 ok

问题:
为什么第一段执行出错,第二段代码执行成功 ?


  1. for /f "delims=" %%i in ('"c:\test\a a\a.exe"') do (
  2. echo ok
  3. )
复制代码
输出 ok

上面代码不变将文件a.exe删除后,再次运行。
出错提示:

'c:\test\a' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

问题:
出错提示为什么不是 ‘c:\test\a a\a.exe’不是内部或外部命令,也不是可运行的程序
或批处理文件 ?

[ 本帖最后由 xahstar 于 2010-7-10 22:26 编辑 ]
作者: sgaizxt001    时间: 2010-7-9 21:59

你添加start看一下呢
  1. for /f "delims=" %%i in ('start "" "c:\test\a a\a.exe" ^| start "" "c:\test\b b\b.exe"') do (
  2. echo ok
  3. )
复制代码

作者: xahstar    时间: 2010-7-10 09:26

原帖由 sgaizxt001 于 2010-7-9 21:59 发表
你添加start看一下呢for /f "delims=" %%i in ('start "" "c:\test\a a\a.exe" ^| start "" "c:\test\b b\b.exe"') do (
echo ok
)


a.exe的输出不能通过管道传递b.exe 。
echo ok 无法执行。
作者: canyuexiaolang    时间: 2010-7-10 09:44

貌似for中有一个很不常用的参数可以解决...usebackq
作者: shuaige100    时间: 2010-7-10 12:15     标题: 回复 1楼 的帖子

???EXE能传递给exe第一次听说

[ 本帖最后由 shuaige100 于 2010-7-10 12:21 编辑 ]
作者: zqz0012005    时间: 2010-7-10 12:26

与for无关,CMD解析命令行引号的机制造成的,应该是正常结果。

一和二运行的命令行分别是
C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\a a\b.exe"
C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"

CMD处理引号的逻辑是:(参见cmd /?
1.   如果符合下列所有条件,那么在命令行上的引号字符将被保留:
- 不带 /S 命令行开关
- 整整两个引号字符
- 在两个引号字符之间没有特殊字符,特殊字符为下列中的一个: <>()@^|
- 在两个引号字符之间有至少一个空白字符
- 在两个引号字符之间有至少一个可执行文件的名称,且该文件存在(推测)

2.  否则,老办法是,看第一个字符是否是一个引号字符,如果是,舍去开头的字符并删除命令行上的最后一个引号字符,保留最后一个引号字符之后的文字。如果不是,所有的引号都保留(推测)

据此可知:
一中cmd.exe执行的命令是:c:\test\a a\c.exe"|"c:\test\a a\a.exe
二中,当a.exe存在时cmd.exe执行的是"c:\test\a a\a.exe",当a.exe不存在时cmd.exe执行的是c:\test\a a\a.exe

PS:个人认为,当初各种系统设计者允许空格作为文件名是一个很不理智的选择,这点也被大量由此导致的问题所凸显。
作者: plp626    时间: 2010-7-10 12:38

关注下,围观中。。。
作者: zqz0012005    时间: 2010-7-10 12:42

注意,C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\a a\b.exe"是由系统执行的,系统把整句作为命令调用,并不认为|是管道符,所有的字符都是普通字符,just a string / a char array。这句与我们直接敲入到CMD中运行是不一样的。
作者: xahstar    时间: 2010-7-10 14:35

原帖由 zqz0012005 于 2010-7-10 12:26 发表
与for无关,CMD解析命令行引号的机制造成的,应该是正常结果。

一和二运行的命令行分别是
C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\a a\b.exe"
C:\WINDOWS\system32\cmd.exe /c "c:\test\ ...


谢谢,明白了些。
但还有两处不明。
1. C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\b b\b.exe"
可以正确执行并输出啊?

2.在for中应当怎样写才能正确执行呢?

[ 本帖最后由 xahstar 于 2010-7-10 14:53 编辑 ]
作者: zqz0012005    时间: 2010-7-10 21:44     标题: 回复 9楼 的帖子

8楼的说明被你无视了吗?

C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\b b\b.exe"
你把它放在开始→运行里面执行,与在CMD里面执行是不一样的。
在CMD里面要想达到同样效果也很简单,在|前面加个^即可。
在CMD中的命令先由CMD解析,再传递给系统。(这种东西在Linux就叫Shell)
CMD解析的结果是,把C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"交给系统执行(当然系统还是把它放在当前CMD中运行),把"c:\test\b b\b.exe"留给自己执行,并把前者的标准输出通过管道传递给后者。

在for中怎么写,你不是已经写了吗?不要把引号放在开头。(让CMD处理引号时不符合第一条逻辑即可)
作者: sgaizxt001    时间: 2010-7-10 22:14

收到,又涨知识了
作者: xahstar    时间: 2010-7-10 22:24

原帖由 zqz0012005 于 2010-7-10 21:44 发表
8楼的说明被你无视了吗?

C:\WINDOWS\system32\cmd.exe /c "c:\test\a a\a.exe"|"c:\test\b b\b.exe"
你把它放在开始→运行里面执行,与在CMD里面执行是不一样的。
在CMD里面要想达到同样效果也很简单,在|前面 ...


对不起,当时没搞明白系统执行与cmd执行的关系。
现在懂了,多谢。




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