0

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?

glass
  • 159
  • 2
  • 12
  • Have you ensured that the CIRCUMFLEX ACCENT (caret) is present when the `curl` command line is parsed? You might try `apple^^^|banana`. – lit Jul 13 '21 at 15:18
  • @lit almost! With that I don't get any error, anyway curl parses "apple^|banana" , so the payload is incorrect. – glass Jul 13 '21 at 15:47
  • What about `curl … ^"%payload%^" …` (with your current `set` command line and delayed expansion **dis**abled)? – aschipfl Jul 13 '21 at 16:40

1 Answers1

1

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.

  • echo /?
  • endlocal /?
  • set /?
  • setlocal /?
  • curl -h or curl --help
Mofi
  • 46,139
  • 17
  • 80
  • 143
  • Thanks, it worked! I think !payload! did the job. I specifically used your second example. – glass Jul 14 '21 at 09:25