batch-filecurlcmdpipewindows-scripting

How to escape pipe in curl in a batch script?


I have a Windows batch script like this:

@echo off
setlocal EnableDelayedExpansion
SET fruit1=apple
SET fruit2=banana
SET "payload={\"name\":\"value\",\"name\":\"%fruit1%^|%fruit2%\"}"
echo %payload%
curl -X POST -H "Content-Type: application/json" -d "%payload%" "<serverURL>"
endlocal

The output is:

{\"name\":\"value\",\"name\":\"apple|banana\"}
Cannot find the specified path

So Curl is not doing anything, that error message is due to the pipe I guess, while the echoed payload is displayed correctly.

As you can see I already tried escaping the pipe with ^ , and setting EnableDelayedExpansion , but nothing works.

Is there a way to pass the correct payload to curl?


Solution

  • I suggest to use:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "fruit1=apple"
    set "fruit2=banana"
    set "payload={\"name\":\"value\",\"name\":\"%fruit1%^|%fruit2%\"}"
    setlocal EnableDelayedExpansion
    echo !payload!
    curl.exe -X POST -H "Content-Type: application/json" -d "!payload!" "<serverURL>"
    endlocal
    endlocal
    

    The environment variables are defined while delayed environment variable expansion is disabled which results in processing each command line with command SET at beginning only once by the Windows command processor.

    See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

    The vertical bar must be escaped nevertheless with a caret character to be interpreted as literal character and not as pipe redirection operator.

    Then delayed expansion is enabled and used on referencing the string value assigned to the environment variable payload by using ! around the environment variable name instead of %.

    It would be also possible to use in this special case:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    set "fruit1=apple"
    set "fruit2=banana"
    set "payload={\"name\":\"value\",\"name\":\"%fruit1%^|%fruit2%\"}"
    echo !payload!
    curl.exe -X POST -H "Content-Type: application/json" -d "!payload!" "<serverURL>"
    endlocal
    

    The three lines defining the three environment variables do not contain an exclamation mark and there is also no other string get from somewhere outside the batch file. For that reason it is possible to enable delayed environment variable expansion with the second command line and let the Windows command processor double process all command lines. The environment variables fruit1 and fruit2 could be referenced in this case also with using delayed expansion by using as fifth command line:

    set "payload={\"name\":\"value\",\"name\":\"!fruit1!^|!fruit2!\"}"
    

    To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.