Maz*_*aka 7 windows cmd batch-file
使用^符号输入带有参数的多行命令时使用双引号来使用带空格的字符串^符号也会被传递,有人可以解释这是什么方式吗?
working.cmd
@echo off
call openfiles.cmd ^
C:\dir\filename.txt ^
C:\another_dir\another_file.txt
Run Code Online (Sandbox Code Playgroud)
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"
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我得到的错误
C:\>call openfiles.cmd "C:\dir with spaces\file with spaces.txt" ^
ELSE was unexpected at this time.
Run Code Online (Sandbox Code Playgroud)
问题是,第二行开头的引号将被多行插入符号转义.
因此,行中的最后一个引号开始引用而不是停止引用,因此第二行中的插入符号作为普通字符处理.
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"
Run Code Online (Sandbox Code Playgroud)
插入符号逃脱了下一个角色,因此角色会失去所有特效.
如果下一个字符是换行符,则删除此字符并取下一个字符(即使这也是换行符).
通过这个简单的规则,你可以解释像
echo #1 Cat^&Dog
echo #2 Cat^
&Dog
echo #3 Redirect to > Cat^
Dog
setlocal EnableDelayedExpansion
set linefeed=^
echo #4 line1!linefeed!line2
Run Code Online (Sandbox Code Playgroud)
#3 创建一个名为"Cat Dog"的文件,因为空间已被转义,并且不再作为分隔符.
但它仍有可能打破这个规则!
你只需要在插入符号前面放置任何重定向,它仍然会丢弃换行符(多行仍然有效),但下一个字符不再被转义.
echo #5 Line1< nul ^
& echo Line2
Run Code Online (Sandbox Code Playgroud)
所以你也可以使用它来构建你的多线命令
call openfiles.cmd < nul ^
"C:\dir with spaces\file with spaces.txt" < nul ^
"C:\another dir with spaces\another file with spaces.txt"
Run Code Online (Sandbox Code Playgroud)
或者使用宏
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"
Run Code Online (Sandbox Code Playgroud)
简而言之:
"字符需要^转义,否则 cmd 会逐字复制出现在对之间的^字符。"
警告:^按字面意思复制插入符号后面的字符,使其失去任何元字符功能(如果有)。在多行场景中,不仅换行符/换行符会被逐字复制,而且新行中的第一个字符也会被转义
解释:
^ 元字符以下定义摘自Daniel Colascione于 2011 年 4 月 23 日发表的文章“每个人都以错误的方式引用命令行参数”的一个小节
更好的引用方法
虽然
"元字符不能完全保护命令行中的元字符免受意外的 shell 解释,但^元字符可以。当 cmd 转换命令行并看到 a 时^,它会忽略 ^ 字符本身,并将下一个字符逐字复制到新命令行,无论是否是元字符。 这就是为什么^用作行继续字符:它告诉 cmd 将后续换行符复制为自身,而不是将该换行符视为命令终止符。如果我们^在参数字符串中添加每个元字符作为前缀,cmd 就会将该字符串转换为我们想要使用的字符串。
现在是与所提出的问题相关的重要部分:
对字符进行转义也
^"很重要:否则,cmd 会逐字复制^出现在对之间的字符",从而破坏该过程中的参数字符串。
请注意,当您 时^", 会"失去其引用功能,因此必须小心。
没有^-转义"
"c:\Program^
Files\test.bat"
Run Code Online (Sandbox Code Playgroud)
变成
"c:\Program^
Files\test.bat"
Run Code Online (Sandbox Code Playgroud)
带^-转义"
^"c:\Program^
Files\test.bat^"
Run Code Online (Sandbox Code Playgroud)
变成
"c:\Program Files\test.bat"
Run Code Online (Sandbox Code Playgroud)
并执行程序
请注意,^对引号进行 - 转义会使它们失去引用功能,因此该命令也可以执行为:c:\Program^ Files\test.bat。我们通常将其放在引号中的原因是为了删除空格元字符的分隔功能,但是转义空格字符的插入符提供了相同的功能。
使用^-escaping ",但空格移至上一行
^"c:\Program ^
Files\test.bat^"
Run Code Online (Sandbox Code Playgroud)
变成
"c:\Program Files\test.bat"
Run Code Online (Sandbox Code Playgroud)
但命令行报告“c:\Program”无法识别...
这是因为第一行的空格字符和转义"字符将被解释为分隔符而不是字符。^<space>
在第二个示例中, the<space>是换行符中 a 之后的第一个字符^,因此被转义并解释为字符而不是分隔符。
来源: 微软博客文章
| 归档时间: |
|
| 查看次数: |
8085 次 |
| 最近记录: |