将目录添加到 PATH 有条件地失败,C:\Program Files (x86) 已经在 PATH 中

Prepend directory to PATH conditionally fails with C:\Program Files (x86) is already in PATH

Windows 10 cmd 脚本问题。

尝试在 .cmd 脚本中有条件地更新我的 PATH 环境变量。我想根据另一个环境变量的存在向 PATH 添加一些内容。如果未设置环境变量,则不应向 PATH 添加任何内容。如果已设置,请将其添加到前面。

这是我的最小可重现示例。将以下内容保存到磁盘上的 script.cmd 文件中:

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%)

然后运行它通过从命令行执行script.cmd文件

D:\script.cmd

结果:

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

以上均为模拟示例。即使我没有明确地将 C:\program files (x86)\my company app 添加到 PATH 开始,在此脚本之前 运行 的其他脚本也会做类似的事情(即:Visual Studio 的 vcvars32.bat)

我认为这与空格和遗漏引号有关。但经过一些实验,它与初始 PATH 中的 (x86)\ 序列有关。

我该如何解决?

如果正文:

,则一行不需要括号
if NOT "%_PERL_PATH%"=="" PATH %_PERL_PATH%;%PATH%
if NOT "%_NASM_PATH%"=="" PATH %_NASM_PATH%;%PATH%
if NOT "%_GIT_PATH%"=="" PATH %_GIT_PATH%;%PATH%

如@Squashman 和@Mofi 所述,如果任何路径字符串包含以下任何符号,上述代码仍可能遇到问题:

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

因为它们是脚本运算符,会混淆解释器。避免这些问题的最佳方法是在可能包含以下内容之一的内容周围加上引号:

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

因此,您可以在 if 语句中安全地使用块括号,即使您实际上并不需要它们:

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%")

现在嵌入的括号位于带引号的字符串中,因此它们不会让解释器误以为您有多个脚本块。

@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

还是我遗漏了一些基本的东西?