Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

windows - 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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...