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

Posted

技术标签:

【中文标题】将目录添加到 PATH 有条件地失败,因为 C:\\Program Files (x86) 已经在 PATH 中【英文标题】:Prepend directory to PATH conditionally fails with C:\Program Files (x86) is already in PATH将目录添加到 PATH 有条件地失败,因为 C:\Program Files (x86) 已经在 PATH 中 【发布时间】:2021-05-16 14:24:19 【问题描述】:

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)\ 序列有关。

我该如何解决?

【问题讨论】:

set "path=c:\program files (x86)\my company app;%PATH%" 我强烈建议使用 Squashman 在上面的评论中建议的语法。环境变量 PATH 的值中的文件夹路径还可以包含 & 并且只有语法 set "PATH=%ProgramFiles(x86)%\my company app;%PATH%" 确保与符号被解释为文字字符而不是 @ 解释的 AND 运算符987654321@。在这种情况下,与命令 SET 相比,命令 PATH 并没有真正的用处。 【参考方案1】:

如果正文,您不需要单行的括号:

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

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

【讨论】:

【参考方案2】:
@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

还是我错过了一些基本的东西?

【讨论】:

以上是关于将目录添加到 PATH 有条件地失败,因为 C:\Program Files (x86) 已经在 PATH 中的主要内容,如果未能解决你的问题,请参考以下文章

使用 maven 将 dll 添加到 java.library.path

尝试将adb添加到PATH变量OSX

可以使用内联语法有条件地将元素添加到数组中吗?

试图将 adb 添加到 PATH 变量 OSX

Thymeleaf - 如何有条件地将选中的属性添加到输入

将附加条件附加到查询