Amessihel
Amessihel

Reputation: 6394

Windows Batch - Protect special characters in a variable

A command needs to use a sequence looking like this one: Z;[%&.:mn=WO. The following call works:

D:\Some_folder> some_command -s "Z;[%&.:mn=WO"

The aim is to embed this call in a batch file, whose behavior isn't than the interactive mode one.

As you can see, there are several special characters, so it has to be protected before use. The batch file looks like the sample below:

set SEQUENCE=<sequence>
call %SOMEREP%\command -s %SEQUENCE% REM blah blah blah

Using set SEQUENCE="Z;[%&.:mn=WO" will fail, and surprisingly, with echo on, the displayed line before execution is exactly the same as the one in interactive mode, which works. Actually, the command line complains that the sequence should only contains ASCII characters in a range of 33-256, and be exactly 12 characters length. As is the quotes became a part of the value.

The attempt to protect each characters fails, with or without quotes:

Other character escaping attempt were tried without success, like quote escaping inside quoted string (""). What point is missed here? Asking before rewriting it in Bash.


Update: I noticed this morning that the reproduced attempts show a double caret (^^). I don't recall why it was done. I let it in place.

Upvotes: 2

Views: 1226

Answers (2)

user7818749
user7818749

Reputation:

Within a batch-file, cmd will consume the first % so just double up on it:

set "SEQUENCE=Z;[%%&.:mn=WO"
some_command -s "%SEQUENCE%"

or if you want to retain the double quotes as part of the value, which is not preferred though:

set SEQUENCE="Z;[%%&.:mn=WO"
some_command -s %SEQUENCE%

If needed to use it without the surrounding double quotes, directly from the command, you need to double up on % and escape the & else the ampersand will be seen as a chaining operator:

some_command -s Z;[%%^&.:mn=WO

a Good source, in table form, for all of the escape sequences can be found on Robvanderwoude

EDIT

To explicitly call it, simply double on the variable % again:

set SEQUENCE="Z;[%%&.:mn=WO"
call some_command -s "%%SEQUENCE%%"

Upvotes: 3

Ben Personick
Ben Personick

Reputation: 3264

Calling the command is generally unnecessary unless you have variables set in a loop and delayed expansion isn't enabled (I used to explicitly avoid delayed expansion and use calls then I needed it instead.)

Assuming that %SOMEREP% was not set in a code block (and therefore no need to Call it) then the following should do.

Essentially just double the % once on the Variable, unless you really do need to call, in which case you quadruple it.

No Call:

Set "_CMD=%SOMEREP%\command"
Set "_SEQUENCE=Z;[%%&.:mn=WO"
"%_CMD%" -s "%_SEQUENCE%"
REM blah blah

Assuming you have actual need to call the command, the following escapes the % twice by using the %%%%

Set "_CMD=%SOMEREP%\command"
Set "_SEQUENCE=Z;[%%%%&.:mn=WO"
call "%_CMD%" -s "%_SEQUENCE%"
REM blah blah

Ignore the original bit about the carrots, I wrote this as I was waking this AM and apparently my brain was still thinking about some commands I was runnign the day prior and got confused, as at the CMD CLI you need to use ^ to escape % to force the delayed expansion of some variables.

Upvotes: 2

Related Questions