在 Windows 命令行中,如何正确转义这样的文件路径?文件名中包含空格、百分比和变量(例如 %cd% 和 %errorlevel%),但不扩展变量?这可能吗?
例如,运行C:\Users\the impossible %cd% filepath.exe
我已经尝试过各种方法来实现百分号转义和引号转义。文件名中没有变量时,这种方法是可行的。但是,如果文件名中包含带有变量的百分号(例如 %cd% 或 %errorlevel%),则无论使用何种转义序列,这种方法似乎都行不通。
我尝试过的事情:
"C:\Users\the impossible %cd% filepath.exe"
"C:\Users\the impossible %%cd%% filepath.exe"
"C:\Users\the impossible ^%cd^% filepath.exe"
在命令行上下文中,转义规则与批处理文件中的转义规则不同。
在命令行上下文中,无法转义百分号,但有一种方法可以将其转义
因此,对于您的情况,您可以使用:
为了能够在文件名中使用插入符号,必须对引号进行转义。
但插入符号无法真正摆脱百分号。
%cd^%
解析器会尝试查找名为的变量cd^
,如果不存在这样的变量,它只会删除插入符号,文本保持不变。空格前的插入符号是保持文件名完整所必需的。
但如果存在这样的变量,命令将失败:
还有第二种变体,可以转义单个百分号
单个百分号可以通过将其转换为
%%=
它之所以有效,是因为第一个百分号只是停留在原处,但扩展
%=
为零。在批处理解析器阶段之一中,解析器尝试扩展
%=cd%
,但变量不能以等号开头,因此它是无害的。此变体是防弹的,没有预定义变量可以破坏它。
这种技术可以调整为只需要一个
%=
来逃避%
在这种情况下必须在命令提示符窗口中使用:
在命令提示符窗口中运行的帮助输出在上一个帮助页面中解释道,包含空格或这些字符之一(或字面解释为密码/密码字符串)
cmd /?
的文件名(或任何其他参数字符串)必须用.&()[]{}^=;!'+,`~
<>|
"
括在内的参数字符串内的所有字符均按字面意思解释,包括(总是)和启用的延迟变量扩展(Windows 默认禁用)的
"
字符。^
%
!
%
被解释为在命令提示符窗口中输入的命令行中环境变量引用的开始/结束(或在FOR循环的情况下为循环变量引用)。但与处理批处理文件中的命令行相比,只有在确实存在同名动态变量或环境%cd%
变量的情况下,才会在执行命令行之前用其他内容替换类似内容。在执行命令提示符窗口中输入的命令行时,文件名字符串中的类似内容不会被空字符串替换,而在处理批处理文件时,如果在处理命令行时没有当前定义同名变量,则会在执行之前从命令行中删除。%UnknownVariable%
%UnknownVariable%
UnknownVariable
%
命令提示符执行和批处理文件执行在处理字符串方面存在差异的原因很简单:%
(这并不像许多人认为的那样不寻常),或者包含多个的命令行%
(例如,用于运行带有选项的图像处理可执行文件)width=75% height=50%
。 此类选项可以像在批处理文件中一样编写,即将要按字面解释的百分号用多个百分号转义,以不将其解释为变量、循环(在FOR循环内)或批处理文件参数字符串引用的width=75%% height=50%%
开头(或结尾) 。%Variable Name%
用户在命令提示符窗口中输入的是引用现有变量。如果没有同名的动态变量或环境Variable Name
变量,则用户输入错误或%Variable Name%
根本没有引用变量。Windows命令处理器在处理批处理文件时,可以预料到批处理文件编写者没有输入错误。在批处理文件中引用在执行前处理命令行时当前不存在的变量也是很常见的。想想如果未使用选项,则使用不存在的可选参数定义的变量,或者在第一次执行命令行时引用的变量尚不存在,但稍后再次执行同一命令行时存在的变量。Windows 命令处理器在处理批处理文件时始终用引用变量的值替换
%Variable Name%
,如果不存在同名的变量,则用空字符串替换,但仅当在处理在命令提示符窗口中输入的命令行或在启动时传递给选项或选项之后的%Variable Name%
变量确实存在时,才替换变量引用。cmd.exe
/C
/K
在命令提示符窗口中运行时的帮助输出
set /?
还描述了最常用的动态变量(不是环境变量)。是动态CD
变量之一。因此,在命令提示符窗口中输入的文件名中的字符串或从批处理文件中读取的字符串始终被解释为动态变量的引用。%cd%
CD
在批处理文件中可以使用:
但是,将百分号留给百分号进行第二个百分号的字面解释的特殊转义规则仅适用于批处理文件,而不适用于命令提示符窗口(因为批处理文件参数字符串引用的可能性)。
以下行既不能在命令提示符窗口也不能在批处理文件中使用,因为其中
^
包含的参数字符串"
被按字面意思解释,而不是转义字符。解决方案不是在
"
此用例中用标准语法规则的特殊例外将参数字符串括起来,而是用^
每个字符(如"
和%
和空格)进行转义并使用:^"
开头指示cmd.exe
按字面意思解释"
,而不是作为双引号参数字符串的开头。^
每个空格字符左边的空格指示cmd.exe
按字面意思解释空格,而不是作为参数字符串分隔符。^%
指示cmd.exe
在这种情况下按字面意思解释百分号,而不是将其作为现有变量的变量引用的开始/结束(或者在FOR循环中作为循环变量引用)。^"
最后指示cmd.exe
按字面意思解释"
,而不是作为双引号参数字符串的结尾。这会导致将带有插入符号的文件名字符串解释为转义字符,并将其
cmd.exe
作为参数字符串:该字符串现在传递给 Windows 内核库函数CreateProcess
"
,由此需要周围的环境来CreateProcess
解析此命令行字符串,以找出要运行的可执行文件,并且文件名包含空格和百分号,以便按字面意思进行解释,就像CreateProcess
对第一个参数字符串用双引号引起来一样。