How to pass a parameter to a batch file containing% without cracking it?

Problem

In the main batch file, the values ​​are pulled from the .txt file (and SET as the values ​​of the variables in this batch file). These values ​​may contain % characters.

They are read from a .txt file without any problems. However, when a variable with a value containing the % character is transferred to the second batch file, the second batch file interprets any % characters as an extension of the variable. (Note: there is no in the second batch file.)

Example

 echo %PERCENTVARIABLE% 

Output: I%LOVE%PERCENT%CHARACTERS%

When it is passed to the second file, and then the echo, (probably) will become IPERCENT , since it interprets %LOVE% and %CHARACTERS% as undefined variables.


Study

I found the syntax for finding and replacing elements inside a line in a batch file, since I thought I could replace the % %% character to avoid it. However, I cannot get it to work.

The syntax is

 set string=This is my string to work with. set string=%string:work=play% echo %string% 

If there is an exit then This is my string to play with. .


Questions

  • Is it possible to infer % characters with the syntax find and replace in a variable? (If not, is there any other way?)
  • Is it advisable to do this? (Can using these escape characters cause any problem in the second batch file, which (as mentioned above) would have no control?)
  • Is there any other way to deal with this problem if the above is not possible?
+5
source share
2 answers

There are no simple rules that can be applied in all situations.

There are several issues that make it difficult to work with string literals in parameters:

  • Poison characters like & , | etc. must be screened or quoted. Escape is difficult, because it can be confusing how many times to escape. Therefore, it is recommended that you usually specify a string.
  • Token delimiters such as <space> , <tab> , = <tab> and , cannot be included in the parameter value if it is not specified.
  • CALL for the script will double any % characters quoted, and there is to prevent this . Running a script without CALL will not double the % characters. But if the script calls another script and expects the control to be returned, then you must use CALL.

So, we have catch-22: On the one hand, we want to specify parameters for protection against poisonous characters and spaces (token separators). But to protect interest, we do not want to indicate.

The only reliable way to reliably pass string literals without regard to cost distortion is to pass them by reference through environment variables.

  • The value to be transmitted must be stored in the environment value. Quotes and / or screens and / or percentage doubling are used to obtain the necessary characters in the value, but it is very convenient.
  • The variable name is passed as a parameter.
  • The script accesses through a delayed value. For example, if the first parameter is the name of the variable containing this value, then it is accessed as !%1! . A delayed extension must be enabled before this syntax can be used - just enter setlocal enableDelayedExpansion .

The beauty of slow expansion - you never have to worry about corruption of poisonous characters, spaces or percentages when expanding a variable.

Here is an example that shows how the following string literal can be passed to a subroutine
"<%|,;^> This & that!" & the other thing! <%|,;^>

 @echo off setlocal enableDelayedExpansion set "parm1="^<%%^|,;^^^^^> This ^& that^^!" & the other thing^! <%%|,;^^^>" echo The value before CALL is !parm1! call :test parm1 exit /b :test echo The value after CALL is !%1! 

- OUTPUT -

 The value before CALL is "<%|,;^> This & that!" & the other thing! <%|,;^> The value after CALL is "<%|,;^> This & that!" & the other thing! <%|,;^> 

But you declare that you have no control over the middle name of the script. So the above elegant solution will not work for you.

If you were to show the code of the 2nd script and show exactly what value you were trying to pass, I could give a solution that would work in this isolated situation. But there are some values ​​that simply cannot be passed unless delayed extension is used with variable names. (Actually another option is to put the value in the file and read the value from the file, but this also requires a change for your second script)

+2
source

may be...?

input.txt

 I%LOVE%PERCENT%CHARACTERS% 

batch1.bat

 @echo off setlocal enableDelayedExpansion set/P var=<input.txt echo(In batch 1 var content: %var% set "var=!var:%%=%%%%!" call batch2.bat "%var%" endlocal exit/B 

batch2.bat

 @echo off set "var=%~1" echo(In batch 2 var content: %var% exit/B 
+1
source

All Articles