Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Special Characters in Batch File

Special characters in batch files are a pain, but I haven't found the right workaround for properly escaping the first two characters of this particular string I'm trying to pass the application.

SET pass=^&AntiBatchfileString
A_Program.exe /pass=%pass%

Things I have tried:

:: Escaping the escape twice, first for ^, second for &.
SET pass=^^^^&AntiBatchfileString
echo %pass%

:: Combining escapes.
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=%first%%second%
echo %pass%

:: Preventing expansion
SET first=^^
SET second=^^&AntiBatchfileString
SET pass=!first!%second%
echo %pass%

:: I got this to print correctly
SET "pass=^&AntiBatchfileString"
echo ^^%pass%

Still when passing the last one it doesn't accept the login, I don't know what the final output is. That got me thinking maybe it was trying to do another expansion when passing the parameter to the application, so I quoted that as well.

SET "pass=^&AntiBatchfileString"
A_Program.exe "/pass=^^%pass%"

It's still not working, I'm not sure what I'm missing at this point.

like image 832
Matthew Rhoden Avatar asked May 19 '16 20:05

Matthew Rhoden


People also ask

What does %% mean in batch file?

Use a single percent sign ( % ) to carry out the for command at the command prompt. Use double percent signs ( %% ) to carry out the for command within a batch file. Variables are case sensitive, and they must be represented with an alphabetical value such as %a, %b, or %c. ( <set> )

How do I use special characters in CMD?

In Windows, you can type any character you want by holding down the ALT key, typing a sequence of numbers, then releasing the ALT key.

How do I escape special characters in CMD?

The Windows command-line interpreter uses a caret character ( ^ ) to escape reserved characters that have special meanings (in particular: & , | , ( , ) , < , > , ^ ).

What does && do in batch file?

&& runs the second command on the line when the first command comes back successfully (i.e. errorlevel == 0 ). The opposite of && is || , which runs the second command when the first command is unsuccessful (i.e. errorlevel != 0 ).


1 Answers

Supposing you want the string ^&AntiBatchfileString literally, this is the best set syntax, as most special characters (^ & ( ) < > | and also the standard delimiters , ; = SPACE TAB) lose their particular meaning as soon as ther are placed in between "", and the "" themselves do not become part of the variable value:

set "pass=^&AntiBatchfileString"

This works only as long as the command extensions are on, which is the Windows default anyway (type cmd /? and see the /E option).

When expanding (reading) a variable like "%pass%" (with enclosing ""), special characters are still treated literally.

However, as soon as you expand it like %pass% (no ""), they get back their special meaning. So you have the following options:

  1. Use set "pass=^^^&AntiBatchfileString", where ^^ escapes the literal ^ and ^& the literal & when reading like %pass%.
  2. Enable delayed expansion (see set /? about how it works and setlocal /? or cmd /? about how to enable it), where the variable value is expanded (read) at a point of time where parsing of special characters has already been completed.

I prefer the latter approach, because no special escaping is necessary, and it can also deal with " appearing in the string value (even if unsymmetrically present).
By the way, " can also be escaped by ^", as long as this does not appear within unescaped "".

Nevertheless, % signs cannot be escaped like ^% in a batch file, because percent expansion happens before escaping, but you need to double them like %% to get one literal one each, independent whether or not the string is in between "".
Note that on the console, %% does not work.

Finally, literal ! are consumed by the delayed expansion feature when enabled, therefore you need to pay particular attention to those in case, by escaping them like ^!, or also by intelligently toggling delayed expansion (hence to enable it only when it is actually needed and to disable it otherwise, when a literal string is provided, like in a set command line, for instance, when expanding a standard variable like %pass% and when reading a for variable like %%I (batch file) or %I (console), for example). Of course this is also not the ultimate solution, because you need setlocal and endlocal to enable/disable delayed expansion, which are intended to localise environment changes, so any variable changes since the most recent setlocal command are lost as soon as endlocal is executed (there are some tricks for passing a variable value over the endlocal barrier though).

like image 60
aschipfl Avatar answered Sep 20 '22 07:09

aschipfl