Windows环境变量值中的引号

3

我试图在Windows批处理文件中实现以下逻辑:“如果%MyBinaryDir%还不在系统的%PATH%开头,则将其放在那里;如果已经存在,则不进行任何操作。”

我有以下代码:

@echo %PATH% | findstr /i /b /c:"%MyBinaryDir%;" > nul || set "PATH=%MyBinaryDir%;%PATH%

这一直运作得非常好,直到我尝试在某个机器上部署时,发现由于某种神秘的原因,%PATH%变量包含了奇数个引号字符。

问题归结为:

@set x="
@echo %x%
@echo %x% | more

第二行打印一个单引号字符。第三行由于引号字符而出错,未能将echo输出流传输到第二个二进制文件(在我的情况下为findstr,但在这个简化的例子中为more)。相反,它会逐字打印字符:
" | more

我的问题是:
(Y)我如何安全地将任意字符串导入到第二个二进制文件中?
和/或
(X)有没有一种条件性地将目录添加到系统路径的方法,以避免这种混乱?

我猜一个解决方案是编写一个名为 echopath.bat 的单独批处理文件,其中包含单行 @echo %PATH%,然后将其作为 @call echopath | findstr ... 调用。但如果可能的话,我想将解决方案全部保留在一个文件中。 - jez
你的应用程序是否需要在目录前加上路径?如果路径不存在,它是否可以被简单地添加到路径中? - Magoo
@Magoo "如果路径中不存在,是否可以将其简单地添加到开头?" 啊,在最初的困惑之后,我明白了。你的意思是“如果它在路径中的任何位置,而不一定在开头”。不,它需要在开头。%PATH% 可能会经常包含多个 C:\PythonXX 目录,我想确保我的选择被提升到前面,并且因此保证在我键入 python.exe 时访问到它。 - jez
2个回答

3
使用延迟扩展来以安全的方式输出任何变量内容。
setlocal EnableDelayedExpansion
set x="
echo !x!
echo !x! | more
echo !path! | more

为了保证空变量的安全性,您可以使用echo()

。关于此,请参阅以下内容:

echo(!path! | more

关于美化/拆分路径变量也存在一个问题:如何在cmd shell中拆分路径变量并使其更易读



0

我建议清理PATH,因为此环境变量中的任何目录路径都不应包含引号。

以下是您任务的示例批处理代码:

@echo off
rem Uncomment the line below for testing with C:\PythonXX
rem already in PATH with an erroneous double quote in PATH.
rem set "PATH=C:\PythonXX;"%PATH%"

echo Path before clean up:
echo.
echo PATH=%PATH%
set "PATH=%PATH:"=%"
echo.
echo Path after clean up:
echo.
echo PATH=%PATH%
if /I "%PATH:~0,12%" NEQ "C:\PythonXX;" set "PATH=C:\PythonXX;%PATH%"
echo.
echo Path modified:
echo.
echo PATH=%PATH%
echo.
pause

请参考如何在环境变量中设置带空格的值以及其他相关答案,了解为什么即使要将一个带有一个或多个引号的值赋给一个变量时,也应该使用set "variable=value"


请参阅如何在环境变量PATH中搜索和替换字符串?。该问题是关于如何将系统__PATH__中的现有Python路径替换为另一个Python路径,以满足您的任务要求。 - Mofi
有时候路径必须包含引号。例如,"C:\Music ; Audio" 中包含目录名中的分号。因此,PATH 包含 PATH=C:\windows\system32;"C:\Music ; Audio" - jeb
1
是的,没错。这个异常是存在的。在我的看法中,带有分号的目录路径根本不应该被允许,因为实际上从来没有理由在目录名中使用分号。然而,在__PATH__中存在奇数引号需要人工进行更正或者脚本尝试查找缺失引号应该插入到__PATH__的哪个目录中,通过验证__PATH__中哪些目录实际存在来完成。在your pretty print/split the path answer中删除var示例中的一个引号就可以展示这个问题。 - Mofi
嗯,我同意在任何理智的世界中它都不应该存在,但我想要利用它不幸存在的事实来工作。谁知道,也许某个重要的二进制文件就在其中一个病态命名的目录中?我曾考虑过使用子字符串方法 - 不幸的是,我要将其提升到路径开头的目录可能并不总是恰好有11个字符(c:\PythonXX只是一个例子),所以硬编码的12就成了问题。我寻找了批处理中查找字符串长度的方法,它们非常可怕 - 整个解决方案似乎越来越棘手。 - jez
1
@jez 如果你需要获取变量字符串的长度,请查看批处理函数strLen - Mofi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接