1

This should be so simple: I don't normally want C:\MinGW\bin\gcc in my PATH, but when I do, I can never remember what to add, so I want a simple batch file named addGccToPath.bat. For starters, I created this simple batch file:

@echo off
set PATH=C:\MinGW\bin;c:\MinGW\bin\gcc;%PATH%

That works, but if I accidentally call it multiple times, my PATH variable keeps getting needlessly longer. So then I thought I'd be clever & make it conditional:

@echo off
if not defined PATH_BEFORE_ADDING_GCC (
   set PATH_BEFORE_ADDING_GCC=%PATH%
   set PATH=C:\MinGW\bin;c:\MinGW\bin\gcc;%PATH_BEFORE_ADDING_GCC%
   echo Added GCC to your path.
) else (
   echo GCC was already added to your path.
)

But when I run it, I get this:

C:\Users\minichm>addgcctopath
\Windows was unexpected at this time.

C:\Users\minichm>

I suspect this is because my PATH variable contains the text "C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\", and the end-parentheses after "x86" terminates the 'if' clause, and the following text "\Windows Kits\8.1..." confuses it, with the resulting error as shown.

How can I conditionally add text to an existing environment variable that already contains parentheses?

phonetagger
  • 7,701
  • 3
  • 31
  • 55
  • Your suspicion is right, the closing `)` is recognized as long as you do not use [delayed expansion](https://ss64.com/nt/delayedexpansion.html)… – aschipfl Jun 25 '22 at 10:45

4 Answers4

2

The ever-loving delayed expansion trap

PATH_BEFORE_ADDING_GCC is not set when the if statement is parsed, so it will be replaced by nothing in the first set path= instruction.

path will then be replaced by %PATH:~1,-1%

Try:

@echo off
if defined PATH_BEFORE_ADDING_GCC (
 echo GCC was already added to your path.
 goto alreadydone
)
set "PATH_BEFORE_ADDING_GCC=%PATH%"
set "PATH=C:\MinGW\bin;c:\MinGW\bin\gcc;%PATH%"
set "PATH=%PATH:~1,-1%"
echo Added GCC to your path.
:alreadydone

Although I'd question the set "PATH=%PATH:~1,-1%" as it will delete the c of the c:... and delete the last character of the original path.

Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign a terminal \, Space or " - build pathnames from the elements - counterintuitively, it is likely to make the process easier.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • Thanks! Your script works if I comment out the line with the tildes. Not sure what that line is for? – phonetagger Jun 25 '22 at 04:24
  • See `set /?` from the prompt. It's substringing - yields the substring of the variable starting at the first number (counting from first character=0; if negative, that number of characters from the end) and length (the second number) - or ending (the second number of characters from the end, if negative). So, that line removes the first character and the last character, which is why I questioned it. I suppose it was originally intended to remove the quotes from an assignment style `set var="something;%orother%"` which is error-prone and somewhat discouraged on SO. – Magoo Jun 25 '22 at 04:33
0

Wrap the value in " so that special characters aren't treated as special

set "PATH_BEFORE_ADDING_GCC=%PATH%"
set "PATH=C:\MinGW\bin;c:\MinGW\bin\gcc;%PATH_BEFORE_ADDING_GCC%"

In fact you should always use the set "var=value" form because it'll prevent accidental cases where one leave blank spaces at the end which will eventually go into the variable

phuclv
  • 37,963
  • 15
  • 156
  • 475
0

It seems your problem are the whitespaces inside the path you added. You can solve this with quotes, but then you have to remove them from your PATH. Tell my if this works:

@echo off
if not defined PATH_BEFORE_ADDING_GCC (
   set PATH_BEFORE_ADDING_GCC=%PATH%
   set PATH="C:\MinGW\bin;c:\MinGW\bin\gcc;%PATH_BEFORE_ADDING_GCC%"
   set PATH=%PATH:~1,-1%
   echo Added GCC to your path.
) else (
   echo GCC was already added to your path.
)
  • This didn't work for me. I still ran into the "`\Windows was unexpected at this time.`" error I was getting before with my normal path. If I change my path to just "`C:\bin`" and run your script, it *says* it added GCC to my path, but it didn't. Plus it stripped off the "C" and "n" from "`C:\bin`", leaving my path just "`:\bi`". I cut and pasted exactly what you show above. – phonetagger Jun 25 '22 at 04:20
0

Here are a couple of other single line, and IMO simpler, alternatives for your specific case:

Using an If statement comparison with variable expansion and replacement:

@If /I Not "%Path%" == "%Path:C:\\MinGW\\bin=%" Set "Path=%Path%C:\MinGW\bin;C:\MinGW\bin\gcc;"

Checking for the content within %Path% using the find.exe utility:

@Path | %SystemRoot%\System32\find.exe /I "C:\MinGW\bin" 1>NUL || Set "Path=%Path%C:\MinGW\bin;C:\MinGW\bin\gcc;"

The basic idea is to just verify that your expanded Path already contains, somewhere within it, the string C:\MinGW\bin, if not, then you add your locations, (which both contain that string), to its content.

Just a footnote about the latter method:
If there is a chance that no variable named Path is defined do not use this method, as the result of Path would be Path=(null), and your resultant variable content would be %Path%C:\MinGW\bin;C:\MinGW\bin\gcc;.

Compo
  • 36,585
  • 5
  • 27
  • 39