Windows PATH上的批处理stringsearch

我正在Windows中编写一个batch file来运行安装后的脚本,需要做的事情之一是将一个目录添加到系统path

该脚本正在工作,它做了这样的事情:

setx Path "%PATH%;c:\path\to\add" -m

这是正确设置path,但如果用户重新安装程序,此脚本可能会运行多次。

我想search的string为c:\path\to\add所以我不会一直添加到系统path相同的path。 在sed ,这在Linux中是相当微不足道的,但我不知道Windows中的命令是什么。 我find了findstr ,但这似乎只适用于文件。

在没有安装额外软件的情况下,这可能在Windows中?

编辑:

我正在使用Inno安装程序来创build安装可执行文件。

冒着一些低估的风险,直到专家提供了一个合理的方式来做到这一点,
如果存在,则从环境变量中删除特定路径,以便可以再次添加:

 set str=%path% :: str is the same with path set str=%str:;C:\Path\To\Add=% :: ";c:\path\to\add" is now removed from str setx Path "%str%;c:\path\to\add" -m :: proceed with setting the path 

如果它实际上是一个路径的一部分,例如c:\path\to\add\somefolder带来删除字符串的风险。 另外,如果路径实际上以\结束,或者它是第一个条目,而实际上并不以它开始; 等等。

可以连续调用各种形式来规避其中的一些,

 set str=%str:;C:\Path\To\Add\;=;% set str=%str:;C:\Path\To\Add;=;% set str=%str:;C:\Path\To\Add\=% set str=%str:C:\Path\To\Add\;=% set str=%str:;C:\Path\To\Add=% 

但是,AAMOF我不确定这是一个理智的做法..

这是我的代码片段,在PATH变量中找到“cvsnt”路径。

 if not "x%PATH:cvsnt=%" == "x%PATH%" goto proceed set PATH=w:\build-repository\cvsnt\2.5.03-2382;%PATH% echo Path added :proceed 

要看的部分是

 not "x%PATH:cvsnt=%" == "x%PATH%" 

首先,我用空字符串替换所有“cvsnt”。 将结果与PATH进行比较,无需更换“cvsnt”。 如果因为“cvsnt”被替换而不相等,那么它存在于PATH中,代码可以继续

%PATH%之前的起始x只是一个占位符来防止某些“不正确的”起始字符。 请参阅批处理文件:查找如果substring是字符串(不在文件中)

setx工具有一个缺点,它不能处理超过1024个字符的变量。

我已经写了一个脚本来处理比限制更长的事件,而不需要安装任何东西。 在这里回答了这个问题: 在Window 7中用NSIS设置环境变量

而不是每次添加路径 – 您可以使用像这样的命令来检查您正在查找的可执行文件是否可以在路径中找到:

 for %f in (cmd.exe) do if [%~$PATH:f]==[] setx Path "%PATH%;c:\path\to\add" -m 

确保检查for /? 阅读更多关于%~$PATH:f的魔法%~$PATH:f

这是一个棘手的解决方法,但遵循您所期望的逻辑:

  1. 搜索PATH
  2. 有条件地添加到PATH

它永远不会从PATH中删除任何东西,所以不用担心会因意外删除某些东西而搞砸Windows。 另外,它直接检查PATH变量,所以你不必担心另一个具有相同名字的文件,它们位于PATH的某个地方。

 echo %PATH% > myTmpPath.tmp find /C /I "c:\path\to\add" myTmpPath.tmp if %ERRORLEVEL% neq 0 setx PATH "%PATH%;c:\path\to\add" del myTmpPath.tmp 

我讨厌使用临时文件,但它很快,很脏,并且可能比从PATH中删除某些东西更安全。

第三行是唯一棘手的问题。 基本上,这条线测试上面FIND命令的结果。 Rob van der Woude说 :

如果找不到搜索字符串, FIND将返回1或更高的错误级别。

他还解释说 :

一些可执行文件返回错误级别的负数! 但是,这可以通过使用以下代码来检查非零返回代码:
IF%ERRORLEVEL%NEQ 0 …