Prepend directory to PATH 有条件地失败,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 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%

正如@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

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