0

Windows 10 cmd script issue.

Trying to conditionally update my PATH environment variable in a .cmd script. I want to prepend something to PATH based on the presence of another environment variable. If the environment variable isn't set, nothing should get added to the PATH. If it is set, prepend it.

Here's my minimal reproducible example. Save the following to a script.cmd file on disk:

echo off
REM Simulate a user with a PATH that has C:\program files (x86) within it
PATH c:\program files (x86)\my company app;%PATH%

set _PERL_PATH=D:\projects\strawberry\perl\bin
set _NASM_PATH=D:\projects\nasm

if NOT "%_PERL_PATH%"=="" (PATH %_PERL_PATH%;%PATH%)
if NOT "%_NASM_PATH%"=="" (PATH %_NASM_PATH%;%PATH%)
if NOT "%_GIT_PATH%"=="" (PATH %_GIT_PATH%;%PATH%)

Then run it by executing the script.cmd file from the command line

D:\script.cmd

Result:

D:\>echo off
\my was unexpected at this time.

The above is all a simulated example. Even if I didn't explicitly add C:\program files (x86)\my company app to PATH to begin with, other scripts that run before this script will do something similar (namely: Visual Studio's vcvars32.bat)

I thought it had to do with spaces and missing quotes. But after some experimentation, it has something do with the (x86)\ sequence in the initial PATH.

How can I fix?

Squashman
  • 13,649
  • 5
  • 27
  • 36
selbie
  • 100,020
  • 15
  • 103
  • 173
  • 1
    `set "path=c:\program files (x86)\my company app;%PATH%"` – Squashman Feb 12 '21 at 21:54
  • 2
    I strongly recommend to use the syntax as suggested by Squashman in the comment above. A folder path in value of environment variable `PATH` could contain also `&` and only the syntax `set "PATH=%ProgramFiles(x86)%\my company app;%PATH%"` makes sure that the ampersand is interpreted as literal character and not as __AND__ operator as explained by [single line with multiple commands using Windows batch file](https://stackoverflow.com/a/25344009/3074564). The command __PATH__ is not really useful in comparison to command __SET__ in this case. – Mofi Feb 13 '21 at 10:22

2 Answers2

1

You don't need the parens for the one line if body:

if NOT "%_PERL_PATH%"=="" PATH %_PERL_PATH%;%PATH%
if NOT "%_NASM_PATH%"=="" PATH %_NASM_PATH%;%PATH%
if NOT "%_GIT_PATH%"=="" PATH %_GIT_PATH%;%PATH%

As noted by @Squashman and @Mofi, the above code could still encounter problems if any of the path strings contains any of these symbols:

&()[]{}^=;!'+,`~

Because they are script operators and can confuse the interpreter. The best way to avoid those problems is to put quotes around content that might contain one of those:

set "path=c:\program files (x86)\my company app;%PATH%"

So with that, you can safely use the block parens in your if statements, even though you don't actually need them:

if NOT "%_PERL_PATH%"=="" (set "PATH=%_PERL_PATH%;%PATH%")
if NOT "%_NASM_PATH%"=="" (set "PATH=%_NASM_PATH%;%PATH%")
if NOT "%_GIT_PATH%"=="" (set "PATH=%_GIT_PATH%;%PATH%")

And now the embedded parens are in a quoted string, so they won't confuse the interpreter into thinking you have multiple script blocks.

jwdonahue
  • 6,199
  • 2
  • 21
  • 43
0
@ECHO OFF
SETLOCAL

set _PERL_PATH=D:\projects\strawberry\perl\bin
set _NASM_PATH=D:\projects\nasm

SET "modifiedpath=%_GIT_path%;%_NASM_PATH%;%_PERL_PATH%;c:\program files (x86)\my company app;%PATH%"

:lopsemis
IF "%modifiedpath:~0,1%" equ ";" SET "modifiedpath=%modifiedpath:~1%"&GOTO lopsemis
IF "%modifiedpath%" neq "%modifiedpath:;;=;%" SET "modifiedpath=%modifiedpath:;;=;%"&GOTO lopsemis
ECHO %PATH%
ECHO %modifiedpath%

:: method2
SET "modifiedpath=c:\program files (x86)\my company app;%PATH%"
IF DEFINED _PERL_PATH SET "modifiedpath=%_perl_path%;%modifiedpath%"
IF DEFINED _nasm_PATH SET "modifiedpath=%_nasm_path%;%modifiedpath%"
IF DEFINED _git_PATH SET "modifiedpath=%_git_path%;%modifiedpath%"
ECHO %PATH%
ECHO %modifiedpath%


GOTO :EOF

or am I missing something fundamental?

Magoo
  • 77,302
  • 8
  • 62
  • 84