带双引号的批处理文件多行命令

时间:2015-11-16 21:16:59

标签: windows batch-file cmd

当使用^符号输入带有参数的多行命令时,如果使用双引号来使用带空格的字符串,那么^符号也会被传递,有人能解释这是什么意思吗?

working.cmd

@echo off 
call openfiles.cmd ^
C:\dir\filename.txt ^
C:\another_dir\another_file.txt

notworking.cmd

@echo off 
call openfiles.cmd ^
"C:\dir with spaces\file with spaces.txt" ^
"C:\another dir with spaces\another file with spaces.txt"

openfiles.cmd看起来像

@echo off
for %%x in (%*) do (

    IF EXIST %%x (
        call "c:\Program Files\Notepad++\notepad++.exe" %%x
    ) ELSE (
        call echo Not found %%x
    )

)

pause

我得到的错误

C:\>call openfiles.cmd "C:\dir with spaces\file with spaces.txt" ^
ELSE was unexpected at this time.

3 个答案:

答案 0 :(得分:7)

问题是,第二行开头的引号将被多行插入符号转义 因此,行中的最后一个引号开始引用而不是停止引用,因此第二行中的插入符号作为普通字符处理。

call openfiles.cmd ^"C:\dir with spaces\file with spaces.txt" ^
**This is a seperate line** "C:\another dir with spaces\another file with spaces.txt"

插入符号规则:

一个插入符号逃脱了下一个角色,因此角色会失去所有特殊效果 如果下一个字符是换行符,则删除该字符并取下一个字符(即使这也是换行符)。

通过这个简单的规则,你可以解释像

这样的事情
echo #1 Cat^&Dog
echo #2 Cat^
&Dog
echo #3 Redirect to > Cat^
 Dog

setlocal EnableDelayedExpansion
set linefeed=^


echo #4 line1!linefeed!line2

#3创建一个名为“Cat Dog”的文件,因为该空间已被转义,不再作为分隔符。

但是仍有可能打破这个规则!
你只需要在插入符号前放置任何重定向,它仍然会丢弃换行符(多行仍然有效),但下一个字符不再被转义。

echo #5 Line1< nul ^
& echo Line2

因此您也可以使用它来构建多线命令

call openfiles.cmd < nul ^
"C:\dir with spaces\file with spaces.txt" < nul ^
"C:\another dir with spaces\another file with spaces.txt"

或使用

set "\n=< nul ^"
call openfiles.cmd %\n%
"C:\dir with spaces\file with spaces.txt" %\n%
"C:\another dir with spaces\another file with spaces.txt"

答案 1 :(得分:2)

在尝试了一些不同的东西后,我设法让它只使用双引号前面的额外空间。 将notworking.cmd更改为以下工作

@echo off 
call openfiles.cmd ^
 "C:\dir with spaces\file with spaces.txt" ^
 "C:\another dir with spaces\another file with spaces.txt"

注意双引号前面的空格

答案 2 :(得分:2)

简而言之:

"字符需要^换行,否则cmd会逐字复制^"之间出现 的字符对

警告^会在插入符号后复制该字符,使它失去任何元字符功能(如果有的话)。在多行方案中,不仅按行复制换行符/换行符,而且新行中的第一个字符也被转义

说明:

^ 插入符号元字符

以下定义是从文章"Everyone quotes command line arguments the wrong way", by Daniel Colascione on April 23, 2011的小节中复制的。

  

一种更好的报价方式

     

尽管"元字符不能完全保护我们的元字符   反对意外的shell解释的命令行,^   元字符可以。 当cmd转换命令行并看到^时,它将忽略^字符本身,并将下一个字符按字面意义复制,无论是否为元字符。   这就是^用作行继续符的原因:它告诉cmd复制后一个   换行本身,而不是将该换行视为命令   终结者。如果我们在参数中的每个元字符前面加上^   字符串,cmd会将其转换为我们要使用的字符串。

,现在与出现的问题有关的重要部分:

  

还要^-转义"字符 很重要:否则,cmd会逐字复制{ {1}}对,在过程中处理参数字符串。

请注意,当您^时,"失去了引用功能,因此必须小心。


演示:

没有^"的转义"

^

成为

"

带有"c:\Program^ Files\test.bat" 的转义"c:\Program^ Files\test.bat"

^

成为

"

并执行程序

请注意,^"c:\Program^ Files\test.bat^" 引起的引号转义会使它们失去引号功能,因此该命令也可以执行为:"c:\Program Files\test.bat" 。我们通常将其放在引号中的原因是为了删除空格元字符的定界功能,但用尖号转义空格字符可以提供相同的功能。

,带有^-转义c:\Program^ Files\test.bat,但空格移到了前一行

^

成为

"

但是命令行报告 'c:\ Program'无法识别...

这是因为第一行带有空格字符,并且^"c:\Program ^ Files\test.bat^" 字符"c:\Program Files\test.bat" 被转义,"被解释为定界符而不是字符。

在第二个示例中,^是换行符中<space>之后的第一个字符,因此被转义并解释为字符而不是定界符。


来源: Microsoft Blog article