Parenthesis in variables inside IF blocks

Viewed 10896

In one of my scripts, I need to use variables that contain parenthesis inside IF statements, but either the string is missing a closing parenthesis or the script exits prematurely with * was unexpected at this time (not actually 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

Output

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

 

I think/know that this is because it thinks the closing parenthesis in C:\Program Files (x86) is the end of the IF statement and it exits before the echo is complete.

Is there a simple way to cirumvent this? Preferably without resorting to

  1. single-line IF statements, as I need to run more than one line of code within them,
  2. copious amounts of GOTOs, as it's not practical,
  3. SETLOCAL EnableDelayedExpansion and using !path! instead of %path%, as I recall reading somewhere that that method doesn't work consistently across OSs.

If not, I'll happily accept the most reliable solution offered, whatever it is.

 

(The scenario isn't up for debate. This is just a refined, concentrated example of the problem. The structure needs to be like this, as it is in my actual script, for reasons I won't go into. It's besides the point and it'll just confuse things and distract from the actual issue.)

5 Answers

my suggestion is :

if (condition_TRUE) goto goodbye_parenthesis_BEGIN

goto goodbye_parenthesis_END  ----- line when previous condition is FALSE ----
:goodbye_parenthesis_BEGIN ----- line when previous condition is TRUE ----

...
variable treatment
...

:goodbye_parenthesis_END

As others already pointed out, the unescaped and unquoted closing parenthesis ) unintentionally ends the parenthesised if block.

Besides escaping, quotation, delayed expansion and "disappearing quotes", there are the following further options:

  1. Use a for meta-variable on the quoted value and remove the quotes by the ~-modifier:

     @echo off
    
     set "PATH=%ProgramFiles(x86)%"
     echo Perfect output:  %PATH%
     if not "%PATH%" == "" (
         rem Variable is defined
         for %%P in ("%PATH%") do echo Unbroken output: %%~P
     )
    
     pause > nul
    
  2. Use the call command to initiate another variable expansion phase, together with doubled (escaped) %-symbols:

     @echo off
    
     set "PATH=%ProgramFiles(x86)%"
     echo Perfect output:  %PATH%
     if not "%PATH%" == "" (
         rem Variable is defined
         call echo Unbroken output: %%PATH%%
     )
    
     pause > nul
    
  3. Do escaping by sub-string substitution, which happens before ^-escaping is detected:

     @echo off
    
     set "PATH=%ProgramFiles(x86)%"
     echo Perfect output:  %PATH%
     if not "%PATH%" == "" (
         rem Variable is defined
         echo Unbroken output: %PATH:)=^)%
     )
    
     pause > nul
    
Related