【问题标题】:CMD nested double quotes in argumentCMD 在参数中嵌套双引号
【发布时间】: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%。我只能控制传递给函数的内容。

【问题讨论】:

    标签: batch-file cmd command-line-arguments double-quotes


    【解决方案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 是的,我把它留给有能力的人,我也更新了我的答案,提到它需要编辑功能。
    猜你喜欢
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2021-11-19
    • 1970-01-01
    相关资源
    最近更新 更多