2014-03-04 28 views
4

我正在編寫一個函數來執行shell命令並在批處理腳本中捕獲其輸出。在函數調用窗口中轉義PIPE字符批處理腳本

: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

我知道我們需要逃避|^在,但如果我嘗試通過^|在功能參數字符串,它它改變^^|再次拋出錯誤。

我錯過了什麼嗎?

回答

8

這是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後進行擴展。

+0

正如你所提到的那樣,正是'^'的問題。我試圖使用'%caret%',但'%% caret %%'做了訣竅。謝謝!! –

3
@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] 
+0

我是批處理腳本的新手,但它看起來像正在取代|通過^ |在你的功能。我試圖在函數參數本身中傳遞它。我可能是錯的,在這種情況下,你能否爲我解密'%x:| =^|%'。 –

+0

+1但是你也必須替換'&<>'來獲得一個通用的解決方案 – jeb

+0

@jeb,是的,你是對的。這是不完整的,但我正在閱讀這個問題,並認爲有些事我沒有看到。 –

相關問題