A bracket in variables inside IF blocks

In one of my scripts, I need to use variables that contain brackets inside IF , but either there is no closing bracket in the line, or the script exits prematurely with * was unexpected at this time (actually not an asterisk), depending on the scenario.

Example

 @echo off SET path=%programFiles(x86)% echo Perfect output: %path% IF NOT "%path%" == "" ( REM Variable is defined echo Broken output: %path% ) pause >nul 

Exit

 Perfect output: C:\Program Files (x86) Broken output: C:\Program Files (x86 

I think / know that this is because he believes that the closing bracket in C:\Program Files (x86) is the end of the IF , and it ends before echo completes.

Is there an easy way to do this? Preferably without resorting to

  • single-line IF , since I need to run several lines of code in them,
  • copious amounts of GOTO s, as this is impractical,
  • SETLOCAL EnableDelayedExpansion and using !path! instead of %path% , as I recall, I read somewhere that this method does not work consistently in the OS.

If not, I will gladly agree to the most reliable solution, whatever it may be.

(The script is not discussed. This is just a sophisticated, concentrated example of the problem. The structure should be as it is in my actual script, for reasons that I wonโ€™t go to. This, moreover, and it just confuses things and distracts from actual problem.)

+9
parentheses batch-file
Aug 14 2018-12-12T00:
source share
3 answers

First of all, you should never use the PATH variable for your own use. This is a reserved environment variable. Using it for your purposes may break your scripts.

The easiest solution is to use a delayed extension. As long as your platform uses CMD.EXE, you have access to the delayed extension.

But there is a relatively simple way to get it working without expansion delay. You can use fading quotes. A quote exists during parsing as the name of a FOR variable when parsing a command. While the runtime does not increase to zero.

 @echo off SET mypath=%programFiles(x86)% echo Perfect output: %mypath% IF NOT "%mypath%" == "" ( REM Variable is defined for %%^" in ("") do echo fixed output: %%~"%mypath%%%~" ) pause >nul 

EDIT - When to use a delayed extension: reply to comment

Usually I use only deferred extension when necessary (more precisely, when it is beneficial). In doing so, I usually find it beneficial in some part of my batch code.

Main advantages

  • Inside the code block to see the changes in the variable in the block
  • When dereferencing a variable name. If the variable name is passed as a parameter, the value of the variable can be obtained through the delayed extension: echo !%1!
  • When using variables as arguments for search and replace operations or substrings: echo !var:%search%=%replace%! , echo !var:%start%,%len%! .
  • Whenever I need to expand a value and not worry about special characters inside it, I need to avoid escaping or quoting: set "var=A&B" & echo !var!

There are other methods for doing the above (except the last one), but slow expansion is the easiest, most effective (fastest to execute) and most reliable option.

Main disadvantages

  • Any FOR variable containing ! in its meaning, it will be damaged when it expands if slow expansion is enabled. I often turn on and off the delayed extension in the FOR loop to get around the problem.
  • It is incorrect to execute a โ€œmacroโ€ (executable code contained within the value of a variable), because before the delayed extension there are many important steps of parsing. So many batch functions are not available for "macros" that run with extension delay.
+6
Aug 14 2018-12-12T00:
source share

) of the allowed variable in the echo statement prematurely closes the IF block.

You can usually fix this by escaping ) with ^) , but you cannot change the environment variable to allow it to be C:\Program Files (x86^) .

You can prevent this problem by surrounding the variable with quotation marks.

As a simpler example:

 > SET bad=a)b > IF 1 == 1 ( ECHO %bad% ) b was unexpected at this time. > IF 1 == 1 ( ECHO "%bad%" ) "a)b" 
+1
Aug 14 2018-12-12T00: 00Z
source share

Forgive me if I read this incorrectly, but is it not โ€œcallingโ€ the control to enter the brackets if I run the broken output?

What about:

 @echo off echo Perfect output: %programFiles(x86)% IF NOT "%programFiles(x86^)%" == "" ( REM Variable is defined echo Broken output: %programFiles(x86)% ) pause >nul 

?

0
Aug 14 2018-12-12T00:
source share



All Articles