CMD 在参数中嵌套双引号

Posted

技术标签:

【中文标题】CMD 在参数中嵌套双引号【英文标题】:CMD nested double quotes in argument 【发布时间】:2012-09-15 03:13:22 【问题描述】:

我在将参数传递给带有嵌套双引号的批处理函数时遇到问题。

这是一个批处理文件的示例:

@SET path_with_space="c:\test\filenamewith space.txt"
@CALL :FUNCTION blaat1, "blaat2 %path_with_space%"
@GOTO :EOF

:FUNCTION
@echo off
echo arg 1: %~1
echo arg 2: %~2
echo arg 3: %~3
GOTO :EOF

输出是:

arg 1: blaat1
arg 2: blaat2 "c:\test\filenamewith
arg 3: space.txt""

我应该怎么做才能使arg 2: blaat2 "c:\test\filenamewith space.txt"? 请注意,我无法调整功能或更改%path_with_space%。我只能控制传递给函数的内容。

【问题讨论】:

【参考方案1】:

我发现了这个,但我所能做的就是将问题转移到不同的区域。

Working with Quotes

@SET 

path_with_space="c:\test\filenamewith space.txt"

:: Remove quotes
@SET _string=###%path_with_space%###
@SET _string=%_string:"###=%
@SET _string=%_string:###"=%
@SET _string=%_string:###=%

@echo %_string%

@CALL :FUNCTION blaat1, "blaat2 %_string%"
@GOTO :EOF

:FUNCTION
@echo off
@echo arg 1: %~1
@echo arg 2: %~2
@echo arg 3: %~3

:EOF


pause

【讨论】:

输出是:arg 1: blaat1 arg 2: blaat2 c:\test\filenamewith space.txt arg 3: 不错的尝试,但引号不见了:(【参考方案2】:

我不相信这是可能的。

无法对空格进行转义以使其不被解释为参数分隔符。在参数中包含空格的唯一方法是将其括在引号中。您需要一些空格来引用,而另一些则不需要,所以这是不可能的。

【讨论】:

看来是这样。我也尝试转义%,但没有成功。【参考方案3】:

就像 dbenham 所说,在没有引号的情况下,似乎不可能在参数中转义空格。 但是,如果您知道 receiver 函数如何获取参数,则有可能。 然后你可以通过转义的延迟变量传递参数,变量不会在调用中扩展,它只会在函数中扩展。 并且有必要在函数中将参数分配给变量,但在良好且可读的代码中可能就是这种情况。

setlocal EnableDelayedExpansion 
set path_with_space="c:\test\filenamewith space.txt"
@CALL :FUNCTION blaat1, "blaat2 ^!path_with_space^!"
GOTO :EOF

:FUNCTION
@echo off
echo arg 1: %~1
echo arg 2: %~2
echo arg 3: %~3
GOTO :EOF 

输出是:

arg 1: blaat1
arg 2: blaat2 "c:\test\filenamewith space.txt"
arg 3:

编辑:批量注入的解决方案

即使应始终禁用延迟扩展,这也有效。 但是你现在需要知道如何在函数中扩展参数。

@echo off
set path_with_space="c:\test\filenamewith space.txt"
CALL :FUNCTION 1 2 ""^^"&call:inject:""
exit/b

:inject
set arg1=blaat1
set arg2=blaat2 %path_with_space%
set arg3=none
exit /b

:FUNCTION
@echo off
set "arg1=%~1"
set "arg2=%~2"
set "arg3=%~3"
echo arg 1: %arg1%
echo arg 2: %arg2%
echo arg 3: %arg3%
GOTO :EOF

【讨论】:

哇,好杰布!尝试转义%,但忘记了!。现在说得通了。谢谢! +1 - 我想到了那个解决方案,但我认为这是不可接受的,因为它需要启用延迟扩展,这是功能的潜在变化。 @dbenham - 我也想到了延迟扩展的问题,但你也可以用 batch injection 解决它 @jeb - 哇。我根本不理解批量注入,但我正在玩它。这很奇怪。 轮到我了——哇。我花了一段时间才弄清楚你的批量注射是如何工作的。不需要最后一个引号,但它确实使引号平衡。非常有趣的是冒号如何在 CALL 中结束标签,之后的所有内容实际上都是注释,直到任何标记分隔符为止。这对我来说是新的。【参考方案4】:

@jeb +1

@davor

为什么不使用简单的双双引号

@SET path_with_space=""c:\test\filenamewith space.txt""
@CALL :FUNCTION blaat1, "blaat2 %path_with_space%", blaat3
@GOTO :EOF

:FUNCTION
@echo off
echo arg 1: %~1
::--------------------
set arg2=%~2
set arg2=%arg2:""="%
::-------------------
echo arg 2: %arg2%
echo arg 3: %~3
GOTO :EOF 

输出是:

arg 1: blaat1
arg 2: blaat2 "c:\test\filenamewith space.txt"
arg 3: blaat3

【讨论】:

这也行,但是... OP的前提是注意我不能调整功能【参考方案5】:

如果您不想使用延迟扩展(您需要编辑 FUNCTION 以完成此操作!):

我建议您在将参数传递给 FUNCTION 之前删除引号(请注意原始示例中的 %path_with_space:"=%"%path_with_space%"),然后您可以将它们放回去,用带引号的版本替换您的路径( %%_arg_2:%path_with_space:"=%=%path_with_space%%%):

@SET path_with_space="c:\test\filenamewith space.txt"
@CALL :FUNCTION blaat1, "blaat2 %path_with_space:"=%"
@GOTO :EOF

:FUNCTION
@echo off
echo arg 1: %~1
set _arg_2=%~2
call echo arg 2: %%_arg_2:%path_with_space:"=%=%path_with_space%%%
echo arg 3: %~3
GOTO :EOF

输出是:

arg 1: blaat1
arg 2: blaat2 "c:\test\filenamewith space.txt"
arg 3:

如果其他参数也包含用引号括起来的路径,您可以对它们都遵循相同的模式

【讨论】:

这也行,但是... OP的前提是注意我不能调整功能 @DavorJosipovic 是的,我把它留给有能力的人,我也更新了我的答案,提到它需要编辑功能。

以上是关于CMD 在参数中嵌套双引号的主要内容,如果未能解决你的问题,请参考以下文章

CMD命令中的参数带有双引号,如何转义双引号?

从批处理文件中的变量中删除双引号会导致 CMD 环境出现问题

请教Linux shell命令中双引号与单引号嵌套的问题

js 单引号嵌套双引号报错?

关于js生成的字符串带有单双引号嵌套的问题

单引号和双引号的一些总结