windows 如何检查 %PATH% 中是否存在目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/141344/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 05:25:31  来源:igfitidea点击:

How to check if directory exists in %PATH%?

windowsbatch-file

提问by Axl

How does one check if a directory is already present in the PATH environment variable? Here's a start. All I've managed to do with the code below, though, is echo the first directory in %PATH%. Since this is a FOR loop you'd think it would enumerate all the directories in %PATH%, but it only gets the first one.

如何检查 PATH 环境变量中是否已经存在目录?这是一个开始。不过,我对下面的代码所做的只是回显 %PATH% 中的第一个目录。由于这是一个 FOR 循环,您会认为它会枚举 %PATH% 中的所有目录,但它只获取第一个。

Is there a better way of doing this? Something like find or findstr operating on the %PATH% variable? I'd just like to check if a directory exists in the list of directories in %PATH%, to avoid adding something that might already be there.

有没有更好的方法来做到这一点?像在 %PATH% 变量上运行的 find 或 findstr 之类的东西?我只想检查 %PATH% 中的目录列表中是否存在一个目录,以避免添加可能已经存在的内容。

FOR /F "delims=;" %%P IN ("%PATH%") DO (
    @ECHO %%~P
)

回答by dbenham

First I will point out a number of issues that make this problem difficult to solve perfectly. Then I will present the most bullet-proof solution I have been able to come up with.

首先我将指出一些使这个问题难以完美解决的问题。然后我将介绍我能想出的最防弹的解决方案。

For this discussion I will use lower case path to represent a single folder path in the file system, and upper case PATH to represent the PATH environment variable.

在本次讨论中,我将使用小写路径表示文件系统中的单个文件夹路径,并使用大写 PATH 表示 PATH 环境变量。

From a practical standpoint, most people want to know if PATH contains the logical equivalent of a given path, not whether PATH contains an exact string match of a given path. This can be problematic because:

从实际的角度来看,大多数人想知道 PATH 是否包含给定路径的逻辑等效项,而不是 PATH 是否包含给定路径的精确字符串匹配。这可能有问题,因为:

  1. The trailing \is optional in a path
    Most paths work equally well both with and without the trailing \. The path logically points to the same location either way. The PATH frequently has a mixture of paths both with and without the trailing \. This is probably the most common practical issue when searching a PATH for a match.

    • There is one exception: The relative path C:(meaning the current working directory of drive C) is very different than C:\(meaning the root directory of drive C)

  2. Some paths have alternate short names
    Any path that does not meet the old 8.3 standard has an alternate short form that does meet the standard. This is another PATH issue that I have seen with some frequency, particularly in business settings.

  3. Windows accepts both /and \as folder separators within a path.
    This is not seen very often, but a path can be specified using /instead of \and it will function just fine within PATH (as well as in many other Windows contexts)

  4. Windows treats consecutive folder separators as one logical separator.
    C:\FOLDER\\ and C:\FOLDER\ are equivalent. This actually helps in many contexts when dealing with a path because a developer can generally append \to a path without bothering to check if the trailing \already exists. But this obviously can cause problems if trying to perform an exact string match.

    • Exceptions: Not only is C:, different than C:\, but C:\(a valid path), is different than C:\\(an invalid path).

  5. Windows trims trailing dots and spaces from file and directory names.
    "C:\test. "is equivalent to "C:\test".

  6. The current .\and parent ..\folder specifiers may appear within a path
    Unlikely to be seen in real life, but something like C:\.\parent\child\..\.\child\is equivalent to C:\parent\child

  7. A path can optionally be enclosed within double quotes.
    A path is often enclosed in quotes to protect against special characters like <space>,;^&=. Actually any number of quotes can appear before, within, and/or after the path. They are ignored by Windows except for the purpose of protecting against special characters. The quotes are never required within PATH unless a path contains a ;, but the quotes may be present never-the-less.

  8. A path may be fully qualified or relative.
    A fully qualified path points to exactly one specific location within the file system. A relative path location changes depending on the value of current working volumes and directories. There are three primary flavors of relative paths:

    • D:is relative to the current working directory of volume D:
    • \myPathis relative to the current working volume (could be C:, D: etc.)
    • myPathis relative to the current working volume and directory

    It is perfectly legal to include a relative path within PATH. This is very common in the Unix world because Unix does not search the current directory by default, so a Unix PATH will often contain .\. But Windows does search the current directory by default, so relative paths are rare in a Windows PATH.

  1. \路径中的尾随是可选的
    大多数路径在带有和不带有尾随 的情况下都能很好地工作\。无论哪种方式,路径在逻辑上都指向相同的位置。PATH 经常包含带有和不带有尾随\. 这可能是在 PATH 中搜索匹配项时最常见的实际问题。

    • 有一个例外:相对路径C:(即 C 盘的当前工作目录)与C:\(即 C 盘的根目录 )非常不同

  2. 某些路径具有备用短名称
    任何不符合旧 8.3 标准的路径都有一个满足标准的备用短格式。这是我经常看到的另一个 PATH 问题,尤其是在商业环境中。

  3. Windows 接受/\作为路径中的文件夹分隔符。
    这种情况并不常见,但是可以使用/代替指定路径,\并且它在 PATH 中(以及在许多其他 Windows 上下文中)可以正常运行

  4. Windows 将连续的文件夹分隔符视为一个逻辑分隔符。
    C:\FOLDER\\ 和 C:\FOLDER\ 是等价的。这实际上在处理路径时在许多情况下都有帮助,因为开发人员通常可以附加\到路径而无需费心检查尾随是否\已经存在。但是,如果尝试执行精确的字符串匹配,这显然会导致问题。

    • 例外情况:不仅是C:,不同于C:\,而且C:\(有效路径)不同于C:\\(无效路径)。

  5. Windows 从文件和目录名称中删除尾随的点和空格。
    "C:\test. "相当于"C:\test"

  6. 当前.\和父..\文件夹符可以在一个路径中出现
    ,不太可能在现实生活中可以看出,但是像C:\.\parent\child\..\.\child\相当于C:\parent\child

  7. 可以选择将路径括在双引号内。
    路径通常用引号括起来以防止特殊字符,如<space>,;^&=. 实际上,任何数量的引号都可以出现在路径之前、之内和/或之后。Windows 会忽略它们,除非是为了防止特殊字符。除非路径包含;,否则 PATH 中永远不需要引号,但引号可能永远存在。

  8. 路径可以是完全限定的或相对的。
    完全限定的路径正好指向文件系统中的一个特定位置。相对路径位置根据当前工作卷和目录的值而变化。相对路径有三种主要风格:

    • D:相对于卷 D 的当前工作目录:
    • \myPath相对于当前工作量(可以是 C:、D: 等)
    • myPath相对于当前工作卷和目录

    在 PATH 中包含相对路径是完全合法的。这在 Unix 世界中很常见,因为 Unix 默认不搜索当前目录,所以 Unix PATH 通常会包含.\. 但是 Windows 默认会搜索当前目录,因此 Windows PATH 中很少有相对路径。

So in order to reliably check if PATH already contains a path, we need a way to convert any given path into a canonical (standard) form. The ~smodifier used by FOR variable and argument expansion is a simple method that addresses issues 1 - 6, and partially addresses issue 7. The ~smodifier removes enclosing quotes, but preserves internal quotes. Issue 7 can be fully resolved by explicitly removing quotes from all paths prior to comparison. Note that if a path does not physically exist then the ~smodifier will not append the \to the path, nor will it convert the path into a valid 8.3 format.

因此,为了可靠地检查 PATH 是否已经包含路径,我们需要一种将任何给定路径转换为规范(标准)形式的方法。~sFOR 变量和参数扩展使用的修饰符是解决问题 1 - 6 和部分解决问题 7 的简单方法。~s修饰符删除封闭引号,但保留内部引号。通过在比较之前从所有路径中明确删除引号,可以完全解决问题 7。请注意,如果路径实际上不存在,则~s修饰符不会将 附加\到路径,也不会将路径转换为有效的 8.3 格式。

The problem with ~sis it converts relative paths into fully qualified paths. This is problematic for Issue 8 because a relative path should never match a fully qualified path. We can use FINDSTR regular expressions to classify a path as either fully qualified or relative. A normal fully qualified path must start with <letter>:<separator>but not <letter>:<separator><separator>, where <separator> is either \or /. UNC paths are always fully qualified and must start with \\. When comparing fully qualified paths we use the ~smodifier. When comparing relative paths we use the raw strings. Finally, we never compare a fully qualified path to a relative path. This strategy provides a good practical solution for Issue 8. The only limitation is two logically equivalent relative paths could be treated as not matching, but this is a minor concern because relative paths are rare in a Windows PATH.

问题~s在于它将相对路径转换为完全限定的路径。这对于问题 8 来说是有问题的,因为相对路径不应该与完全限定的路径匹配。我们可以使用 FINDSTR 正则表达式将路径分类为完全限定的或相对的。正常的完全限定路径必须以<letter>:<separator>但不是开头<letter>:<separator><separator>,其中 <separator> 是\/。UNC 路径始终是完全限定的,并且必须以\\. 在比较完全限定的路径时,我们使用~s修饰符。在比较相对路径时,我们使用原始字符串。最后,我们从不将完全限定的路径与相对路径进行比较。此策略为问题 8 提供了一个很好的实用解决方案。唯一的限制是两个逻辑上等效的相对路径可能被视为不匹配,但这是一个次要问题,因为相对路径在 Windows PATH 中很少见。

There are some additional issues that complicate this problem:

还有一些其他问题使这个问题复杂化:

9) Normal expansion is not reliable when dealing with a PATH that contains special characters.
Special characters do not need to be quoted within PATH, but they could be. So a PATH like C:\THIS & THAT;"C:\& THE OTHER THING"is perfectly valid, but it cannot be expanded safely using simple expansion because both "%PATH%"and %PATH%will fail.

9)在处理包含特殊字符的 PATH 时,正常扩展是不可靠的。
特殊字符不需要在 PATH 中引用,但可以引用。因此,像一个路径 C:\THIS & THAT;"C:\& THE OTHER THING"是完全有效的,但不能使用简单的扩展,因为这两个安全扩展"%PATH%",并%PATH%会失败。

10) The path delimiter is also valid within a path name
A ;is used to delimit paths within PATH, but ;can also be a valid character within a path, in which case the path must be quoted. This causes a parsing issue.

10)路径定界符在路径名中也是有效的
A;用于在 PATH 内定界路径,但;也可以是路径内的有效字符,在这种情况下,路径必须被引用。这会导致解析问题。

jeb solved both issues 9 and 10 at 'Pretty print' windows %PATH% variable - how to split on ';' in CMD shell

jeb 在“漂亮打印”窗口 %PATH% 变量中解决了问题 9 和问题 10 - 如何在“;”上拆分 在 CMD 外壳中

So we can combine the ~smodifier and path classification techniques along with my variation of jeb's PATH parser to get this nearly bullet proof solution for checking if a given path already exists within PATH. The function can be included and called from within a batch file, or it can stand alone and be called as its own inPath.bat batch file. It looks like a lot of code, but over half of it is comments.

因此,我们可以将~s修饰符和路径分类技术与我对 jeb 的 PATH 解析器的变体结合起来,以获得这种几乎防弹的解决方案,用于检查给定的路径是否已存在于 PATH 中。该函数可以在批处理文件中包含和调用,也可以独立并作为自己的 inPath.bat 批处理文件调用。看起来很多代码,但其中一半以上是注释。

@echo off
:inPath pathVar
::
::  Tests if the path stored within variable pathVar exists within PATH.
::
::  The result is returned as the ERRORLEVEL:
::    0 if the pathVar path is found in PATH.
::    1 if the pathVar path is not found in PATH.
::    2 if pathVar is missing or undefined or if PATH is undefined.
::
::  If the pathVar path is fully qualified, then it is logically compared
::  to each fully qualified path within PATH. The path strings don't have
::  to match exactly, they just need to be logically equivalent.
::
::  If the pathVar path is relative, then it is strictly compared to each
::  relative path within PATH. Case differences and double quotes are
::  ignored, but otherwise the path strings must match exactly.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
                           /c:^"^^\"[\][\]" >nul ^
  && set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then do
:: proper comparison with pathVar.
:: Exit with ERRORLEVEL 0 if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
  if "!!"=="" endlocal
  for %%C in ("%%~B\") do (
    echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
                           /c:^"^^\"[\][\]" >nul ^
      && (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
      || (if %abs%==0 if /i "%%~A"=="%%~C" exit /b 0)
  )
)
:: No match was found so exit with ERRORLEVEL 1
exit /b 1

The function can be used like so (assuming the batch file is named inPath.bat):

该函数可以像这样使用(假设批处理文件名为 inPath.bat):

set test=c:\mypath
call inPath test && (echo found) || (echo not found)





通常,检查 PATH 中是否存在路径的原因是因为您想在路径不存在时附加该路径。这通常只需使用类似path %path%;%newPath%path %path%;%newPath%. 但是第 9 期证明了这是不可靠的。

Another issue is how to return the final PATH value across the ENDLOCAL barrier at the end of the function, especially if the function could be called with delayed expansion enabled or disabled. Any unescaped !will corrupt the value if delayed expansion is enabled.

另一个问题是如何在函数结束时跨越 ENDLOCAL 屏障返回最终的 PATH 值,特别是如果可以在启用或禁用延迟扩展的情况下调用该函数。!如果启用延迟扩展,任何未转义都会破坏该值。

These problems are resolved using an amazing safe return technique that jeb invented here: http://www.dostips.com/forum/viewtopic.php?p=6930#p6930

使用 jeb 在此处发明的惊人安全返回技术解决了这些问题:http: //www.dostips.com/forum/viewtopic.php?p=6930#p6930

@echo off
:addPath pathVar /B
::
::  Safely appends the path contained within variable pathVar to the end
::  of PATH if and only if the path does not already exist within PATH.
::
::  If the case insensitive /B option is specified, then the path is
::  inserted into the front (Beginning) of PATH instead.
::
::  If the pathVar path is fully qualified, then it is logically compared
::  to each fully qualified path within PATH. The path strings are
::  considered a match if they are logically equivalent.
::
::  If the pathVar path is relative, then it is strictly compared to each
::  relative path within PATH. Case differences and double quotes are
::  ignored, but otherwise the path strings must match exactly.
::
::  Before appending the pathVar path, all double quotes are stripped, and
::  then the path is enclosed in double quotes if and only if the path
::  contains at least one semicolon.
::
::  addPath aborts with ERRORLEVEL 2 if pathVar is missing or undefined
::  or if PATH is undefined.
::
::------------------------------------------------------------------------
::
:: Error checking
if "%~1"=="" exit /b 2
if not defined %~1 exit /b 2
if not defined path exit /b 2
::
:: Determine if function was called while delayed expansion was enabled
setlocal
set "NotDelayed=!"
::
:: Prepare to safely parse PATH into individual paths
setlocal DisableDelayedExpansion
set "var=%path:"=""%"
set "var=%var:^=^^%"
set "var=%var:&=^&%"
set "var=%var:|=^|%"
set "var=%var:<=^<%"
set "var=%var:>=^>%"
set "var=%var:;=^;^;%"
set var=%var:""="%
set "var=%var:"=""Q%"
set "var=%var:;;="S"S%"
set "var=%var:^;^;=;%"
set "var=%var:""="%"
setlocal EnableDelayedExpansion
set "var=!var:"Q=!"
set "var=!var:"S"S=";"!"
::
:: Remove quotes from pathVar and abort if it becomes empty
set "new=!%~1:"^=!"
if not defined new exit /b 2
::
:: Determine if pathVar is fully qualified
echo("!new!"|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
                           /c:^"^^\"[\][\]" >nul ^
  && set "abs=1" || set "abs=0"
::
:: For each path in PATH, check if path is fully qualified and then
:: do proper comparison with pathVar. Exit if a match is found.
:: Delayed expansion must be disabled when expanding FOR variables
:: just in case the value contains !
for %%A in ("!new!\") do for %%B in ("!var!") do (
  if "!!"=="" setlocal disableDelayedExpansion
  for %%C in ("%%~B\") do (
    echo(%%B|findstr /i /r /c:^"^^\"[a-zA-Z]:[\/][^\/]" ^
                           /c:^"^^\"[\][\]" >nul ^
      && (if %abs%==1 if /i "%%~sA"=="%%~sC" exit /b 0) ^
      || (if %abs%==0 if /i %%A==%%C exit /b 0)
  )
)
::
:: Build the modified PATH, enclosing the added path in quotes
:: only if it contains ;
setlocal enableDelayedExpansion
if "!new:;=!" neq "!new!" set new="!new!"
if /i "%~2"=="/B" (set "rtn=!new!;!path!") else set "rtn=!path!;!new!"
::
:: rtn now contains the modified PATH. We need to safely pass the
:: value accross the ENDLOCAL barrier
::
:: Make rtn safe for assignment using normal expansion by replacing
:: % and " with not yet defined FOR variables
set "rtn=!rtn:%%=%%A!"
set "rtn=!rtn:"=%%B!"
::
:: Escape ^ and ! if function was called while delayed expansion was enabled.
:: The trailing ! in the second assignment is critical and must not be removed.
if not defined NotDelayed set "rtn=!rtn:^=^^^^!"
if not defined NotDelayed set "rtn=%rtn:!=^^^!%" !
::
:: Pass the rtn value accross the ENDLOCAL barrier using FOR variables to
:: restore the % and " characters. Again the trailing ! is critical.
for /f "usebackq tokens=1,2" %%A in ('%%^ ^"') do (
  endlocal & endlocal & endlocal & endlocal & endlocal
  set "path=%rtn%" !
)
exit /b 0

回答by Randy

I haven't done any batch file programming in a while, but:

我有一段时间没有做过任何批处理文件编程,但是:

echo ;%PATH%; | find /C /I ";<string>;"

should give you 0 if string is not found and 1 or more if it is.

如果没有找到字符串,应该给你 0,如果找到,应该给你 1 或更多。

EDIT: Added case-insensitive flag, thanks to Panos.

编辑:感谢 Panos,添加了不区分大小写的标志。

回答by bert bruynooghe

Another way to check if something is in the path is to execute some innocent executable that is not going to fail if it's there, and check the result. As an example, next code snippet checks if mavenis in the path:

检查路径中是否存在某些东西的另一种方法是执行一些无辜的可执行文件,如果它在那里就不会失败,然后检查结果。例如,下一个代码片段检查maven是否在路径中:

mvn --help > NUL 2> NUL 
if errorlevel 1 goto mvnNotInPath

So I try to run mvn --help, ignore the output (don't actually want to see the help if maven is there)( > NUL), and also don't display the error message if maven was not found (2> NUL).

所以我尝试运行mvn --help,忽略输出(如果 maven 存在,实际上不想看到帮助)(> NUL),并且如果未找到 maven 也不显示错误消息(2>无)。

回答by Aacini

After reading the answers here I think I can provide a new point of view: if the purpose of this question is to know if the path to a certain executable fileexists in %PATH%and if not, insert it (and this is the only reasonto do that, I think), then it may solved in a slightly different way: "How to check if the directory of a certain executable program exist in %PATH%"? This question may be easily solved this way:

在这里阅读的答案后,我想我可以提供一个新的观点:如果这个问题的目的是要知道如果路径有一定的可执行文件的存在%PATH%,如果没有,将其插入(和这是唯一的原因做那个,我认为),那么它可能会以稍微不同的方式解决:“如何检查 %PATH% 中是否存在某个可执行程序的目录”?这个问题可以通过这种方式轻松解决:

for %%p in (programname.exe) do set "progpath=%%~$PATH:p"
if not defined progpath (
   rem The path to programname.exe don't exist in PATH variable, insert it:
   set "PATH=%PATH%;C:\path\to\progranname"
)

If you don't know the extension of the executable file, just review all of them:

如果您不知道可执行文件的扩展名,只需查看所有扩展名:

set "progpath="
for %%e in (%PATHEXT%) do (
   if not defined progpath (
      for %%p in (programname.%%e) do set "progpath=%%~$PATH:p"
   )
)

回答by Atif Aziz

Using forand delims, you cannot capture an arbitrary number of fields (as Adam pointed outas well) so you have to use a looping technique instead. The following command script will list each path in the PATHenvironment variable on a separate line:

使用forand delims,您不能捕获任意数量的字段(正如Adam 所指出的),因此您必须使用循环技术。以下命令脚本将PATH在单独的行中列出环境变量中的每个路径:

@echo off 
setlocal 
if "%~1"=="" (
    set PATHQ=%PATH%
) else (
    set PATHQ=%~1 ) 
:WHILE
    if "%PATHQ%"=="" goto WEND
    for /F "delims=;" %%i in ("%PATHQ%") do echo %%i
    for /F "delims=; tokens=1,*" %%i in ("%PATHQ%") do set PATHQ=%%j
    goto WHILE 
:WEND

It simulates a classical whilewendconstruct found in many programming languages. With this in place, you can use something like findstrto subsequently filter and look for a particular path. For example, if you saved the above script in a file called tidypath.cmdthen here is how you could pipe to findstr, looking for paths under the standard programs directory (using a case-insensitive match):

它模拟了许多编程语言中的经典while... wend构造。有了这个,你可以使用类似的东西findstr来随后过滤和寻找特定的路径。例如,如果您将上述脚本保存在一个名为的文件中,tidypath.cmd那么您可以通过以下方式通过管道连接到findstr,在标准程序目录下查找路径(使用不区分大小写的匹配):

> tidypath | findstr /i "%ProgramFiles%"

回答by mousio

This will look for an exact but case-insensitive match, so mind any trailing backslashes etc.:

这将寻找一个精确但不区分大小写的匹配,所以请注意任何尾随反斜杠等:

for %P in ("%path:;=";"%") do @if /i %P=="PATH_TO_CHECK" echo %P exists in PATH

or, in a batch file (e.g. checkpath.bat) which takes an argument:

或者,在一个带有参数的批处理文件(例如 checkpath.bat)中:

@for %%P in ("%path:;=";"%") do @if /i %%P=="%~1" echo %%P exists in PATH

In the latter form, one could call e.g. checkpath "%ProgramFiles%"to see if the specified path already exists in PATH.

在后一种形式中,可以调用例如checkpath "%ProgramFiles%"查看指定路径是否已存在于 PATH 中。

Please note that this implementation assumes no semicolons or quotes are present inside a single path item.

请注意,此实现假定单个路径项中不存在分号或引号。

回答by Kevin Edwards

You can also use substring replacement to test for the presence of a substring. Here I remove quotes to create PATH_NQ, then I remove "c:\mydir" from the PATH_NQ and compare it to the original to see if anything changed:

您还可以使用子字符串替换来测试子字符串是否存在。在这里,我删除引号以创建 PATH_NQ,然后从 PATH_NQ 中删除 "c:\mydir" 并将其与原始文件进行比较以查看是否有任何更改:

set PATH_NQ=%PATH:"=%
if not "%PATH_NQ%"=="%PATH_NQ:c:\mydir=%" goto already_in_path
set PATH=%PATH%;c:\mydir
:already_in_path

回答by Noam Manos

Add Directory to PATH if not already exists:

如果尚不存在,则将目录添加到 PATH:

set myPath=c:\mypath
For /F "Delims=" %%I In ('echo %PATH% ^| find /C /I "%myPath%"') Do set pathExists=%%I 2>Nul
If %pathExists%==0 (set PATH=%myPath%;%PATH%)

回答by indiv

I took your implementation using the forloop and extended it into something that iterates through all elements of the path. Each iteration of the for loop removes the first element of the path (%p) from the entire path (held in %q and %r).

我使用for循环获取您的实现并将其扩展为遍历路径的所有元素的内容。for 循环的每次迭代都会从整个路径(保存在 %q 和 %r 中)中删除路径的第一个元素 (%p)。

@echo off
SET MYPATHCOPY=%PATH%

:search
for /f "delims=; tokens=1,2*" %%p in ("%MYPATHCOPY%") do (
   @echo %%~p
   SET MYPATHCOPY=%%~q;%%~r
)

if "%MYPATHCOPY%"==";" goto done;
goto search;

:done

Sample output:

示例输出:

Z:\>path.bat
C:\Program Files\Microsoft DirectX SDK (November 2007)\Utilities\Bin\x86
c:\program files\imagemagick-6.3.4-q16
C:\WINDOWS\system32
C:\WINDOWS
C:\SFU\common\
c:\Program Files\Debugging Tools for Windows
C:\Program Files\Nmap

回答by Adam Mitz

If your question was "why doesn't this cmd script fragment work?" then the answer is that for /fiterates over lines. The delimssplit lines into fields, but you're only capturing the first field in %%P. There is no way to capture an arbitrary number of fields with a for /floop.

如果您的问题是“为什么这个 cmd 脚本片段不起作用?” 那么答案是for /f遍历行。将delims分割线分成多个字段,但您只捕获%%P. 无法通过for /f循环捕获任意数量的字段。