【问题标题】:Escape PIPE character in a function call windows Batch script在函数调用窗口批处理脚本中转义 PIPE 字符
【发布时间】:2014-04-05 15:41:52
【问题描述】:

我正在编写一个函数来执行 shell 命令并在批处理脚本中捕获其输出。

:runShellCmd
   setlocal EnableDelayedExpansion
   SET lf=-
   FOR /F "delims=" %%i IN ('%~1') DO if "%out%" == "" (set out=%%i) else (set out=!out!%lf%%%i)
   echo "Cmd output: %out%"
   SET "funOut=%out%"
ENDLOCAL & IF "%~1" NEQ "" SET %~2=%out%
goto :EOF

我已经成功地传递了简单的命令并获得了输出。但是对于像

这样的电话

CALL :runShellCmd "echo Jatin Kumar | find /c /i "jatin"" 失败并出现错误unexpected | character。

我知道我们需要在 for 中使用 ^ 转义 |,但如果我尝试在函数参数字符串中传递 ^|,它会将其更改为 ^^|,这又会引发错误。

我错过了什么吗?

【问题讨论】:

    标签: windows batch-file escaping call pipe


    【解决方案1】:

    这是CALL 命令的效果。

    CALL 命令在一个批处理解析器阶段中将所有插入符号加倍。
    通常你不会看到这一点,因为插入符号将在加倍后直接用作转义字符。

    看到这个

    call echo ^^^^
    call call echo ^^^^
    call call call echo ^^^^
    
    call echo "^^^^"
    call call echo "^^^^"
    call call call echo "^^^^"
    

    输出

    ^^
    ^^
    ^^
    "^^^^^^^^"
    "^^^^^^^^^^^^^^^^"
    "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
    

    但是你怎么能逃脱你的管道字符呢?
    你不能!

    但您可以在函数中添加脱字符号。

    :runShellCmd
       setlocal EnableDelayedExpansion
       set "param=%~1"
       set param
       set "param=!param:^^=^!"
       for .... ('!param!')
    

    或者你可以在调用你的函数时使用转义技巧。

    set "caret=^"
    CALL :runShellCmd "echo Jatin Kumar %%caret%%| find /c /i "
    

    这可行,因为%%caret%% 将在CALL caret doubling phase 之后展开。

    【讨论】:

    • 正如您所提到的,这正是^ 的问题。我想使用%caret%,但%%caret%% 成功了。谢谢!!
    【解决方案2】:
    @echo off
        setlocal enableextensions disabledelayedexpansion 
    
        call :test "echo(this|find "t""
        exit /b
    
    :test
        set "x=%~1"
        for /f "delims=" %%f in ('%x:|=^|%') do echo [%%f]
    

    我想我错过了一些东西,因为这对我有用。

    已编辑 - 这应该是更通用的解决方案。不是防弹的,而是骷髅。

    @echo off
        setlocal enableextensions disabledelayedexpansion 
    
        call :test "(echo(this&echo(that)|find "t" 2>nul|sort&echo end"
        exit /b
    
    :test
        set "x=%~1"
        set "x=%x:|=^|%"
        set "x=%x:>=^>%"
        set "x=%x:<=^<%"
        set "x=%x:&=^&%"
        set "x=%x:)=^)%"
        for /f "delims=" %%f in ('%x%') do echo [%%f]
    

    【讨论】:

    • 我是批处理脚本的新手,但看起来正在替换 |由 ^|在你的功能中。我试图将它传递给函数参数本身。我可能错了,那请你帮我解密%x:|=^|%。
    • @jeb,是的,你是对的。它不完整,但我正在阅读这个问题并认为有一些我没有看到的东西。
    • @JatinKumar,是的,你是对的,这就是我正在做的事情。问题不在于通过管道,问题在于管道必须在for /f 内转义才能正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多