【问题标题】:Remove unwanted directory from PATH using cmd file使用 cmd 文件从 PATH 中删除不需要的目录
【发布时间】:2017-09-01 11:39:59
【问题描述】:

我找到了一个solution,可以直接通过 Windows 命令行从环境变量 PATH 中删除某个目录。但我想通过在 cmd 文件中发出命令来实现相同的结果。

我可以做的是回显我想要设置 PATH 的结果,如果我放的话

echo %PATH:D:\dir-path;=%

进入我的 cmd 文件。但是如果我写

set PATH=%PATH:D:\dir-path;=%

PATH 仅包含我要删除的目录。

此外,我想为导向器路径使用一个变量,但如果我尝试这样做,结果会更糟。我放了

set dirPath=D:\dir-path
echo %PATH:%dirPath%;=%

我得到的只是dirPath;=

我不知道如何解决这个问题,所以如果有人能提供帮助,我将不胜感激。

编辑 1

正如@Anders 建议的那样,我现在有了:

@echo off

set exampleRemoveDir=d:\bar

REM If I use %exampleRemoveDir% it does not work at all.
call :removeFromPath exampleRemoveDir & set result=%ERRORLEVEL%

:removeFromPath
set removeDir=%~1

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removeDir%;=!
if "%_%" == "%PATH%" set _=!PATH:%removeDir%=!
endlocal & set PATH=%_%
echo %PATH%
exit /b 0

但使用该解决方案 PATH 仍然保持不变。如果我不限定删除步骤位,代码将完美运行,因为我想为多个目录执行此操作,如果没有这么好的帮手为我做这项工作,那将是一个真正的痛苦。

编辑 2

因为这似乎比我想象的要复杂,所以这是我迄今为止未更改的完整脚本。

@echo off
::  Switching Perl version from ActivePerl to StrawberryPerl or the other way round depending on which paths are set in
::  PATH.

::  Directories for ActivePerl
set activePerl_SiteBinPath=D:\ProgramFiles\ActivePerl\site\bin
set activePerl_BinPath=D:\ProgramFiles\ActivePerl\bin

::  Directories for StrawberryPerl
set strawberryPerl_SiteBinPath=D:\ProgramFiles\StrawberryPerl\perl\site\bin
set strawberryPerl_BinCPath=D:\ProgramFiles\StrawberryPerl\c\bin
set strawberryPerl_BinPath=D:\ProgramFiles\StrawberryPerl\perl\bin

:: Determine which of the directories are present in PATH and which are not.
call :isInPath %activePerl_SiteBinPath% & set foundActivePerl_SiteBinPath=%ERRORLEVEL%
call :isInPath %activePerl_BinPath% & set foundActivePerl_BinPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_SiteBinPath% & set foundStrawberryPerl_SiteBinPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_BinCPath% & set foundStrawberryPerl_BinCPath=%ERRORLEVEL%
call :isInPath %strawberryPerl_BinPath% & set foundStrawberryPerl_BinPath=%ERRORLEVEL%

:: Test
call :removeFromPath %strawberryPerl_SiteBinPath% & set removedStrawberryPerl_SiteBinPath=%ERRORLEVEL%

rem if /i %foundActivePerl_SiteBinPath% equ 0 if /i %foundActivePerl_BinPath% equ 0 (
rem     if /i %foundStrawberryPerl_SiteBinPath% neq 0 if /i %foundStrawberryPerl_BinPath% neq 0 if  /i %foundStrawberryPerl_BinCPath% neq 0 (
rem         echo Switching from ActivePerl to StrawberryPerl.
rem         TODO
rem         exit /b 0
rem     )
rem )
rem 
rem if /i %foundStrawberryPerl_SiteBinPath% equ 0 if /i %foundStrawberryPerl_BinPath% equ 0 if /i %foundStrawberryPerl_BinCPath% equ 0 (
rem     if /i %foundActivePerl_SiteBinPath% neq 0 if /i %foundActivePerl_BinPath% neq 0 (
rem         echo Switching from StrawberryPerl to ActivePerl.
rem         TODO
rem         exit /b 0
rem     )
rem )

:: Error
:: TODO
exit /b

:isInPath
::  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 pathVar path is not found in %PATH%.
::      2 if parhVar path is missing or undefined.

:: Error checking
if "%~1"=="" exit /b 2

set pathVar=%~1

for /f %%i in ('echo ";%%PATH%%;" ^| find /c /i ";%pathVar%;"') do set /a foundPathVar=%%i

if /i %foundPathVar% equ 0 (
    exit /b 1
)
exit b/ 0

:removeFromPath
::  Removes a given directory from environment variable PATH if the directory exists within PATH.
::
::  The result is returned as the ERRORLEVEL:
::      0 if the given directory was removed from PATH or if it didn't exist in PATH.
::      1 if no directory was given or the directory is undefined.

:: Error checking
if "%~1"=="" exit /b 2

set removeDir=%~1

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removeDir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removeDir%=!
endlocal & set PATH=%_%
echo %PATH%

exit /b 0

编辑 3

感谢@Anders 从路径中删除目录现在可以正常工作。我删除了上面对未定义参数的错误检查,并在函数调用的参数周围添加了%。 但不知何故,:isInPath 现在总是返回零。就我而言,这已经奏效了……:/此外,使用当前代码(将% 添加到所有函数参数中),无论在调用:removeFromPath 之后是否有pause,cmd 总是直接关闭。真是气死人了!

【问题讨论】:

  • 为什么要从%PATH% 变量中删除位置?您是否知道您在批处理/cmd.exe 会话中使用SET "PATH=%PATH:match=replace%" 所做的任何更改都不是永久性的,它只会持续与该 cmd 实例一样长。您能否提供更多批处理文件,以便我们更好地处理您希望实现的目标。
  • @Lilo,您的脚本中是否还有其他可能导致问题的函数?我测试了 Anders 的脚本,它确实从路径中删除了目录。
  • 从长远来看,我想使用 setx,但只要它不能与 set 一起使用,我为什么要使用 setx?我已经安装了 ActivePerl 以及 es StrawberryPerl,我希望能够通过简单地双击批处理脚本来切换当前使用的 Perl 变体。为了实现这一点,我必须检查哪些目录当前位于 PATH 中,因此必须删除或添加才能从当前使用的变体切换到另一个。
  • 如果您将 %exampleRemoveDir% 更改为 exampleRemoveDir,它将永远无法工作。在您的编辑中,您不会在调用 :removeFromPath 后停止脚本,并且批处理的常规部分将执行 :removeFromPath 作为脚本的一部分!复制并粘贴我的整个示例,然后重试...
  • @Anders 好吧,我发布了到目前为止的所有内容。如果我使用%exampleRemoveDir% :removeFromPath 内的回声甚至不会发出。但我想我在另一个层面上做错了什么...... -.-

标签: windows batch-file cmd environment-variables


【解决方案1】:

如果您想使用另一个变量作为变量替换的一部分,您需要使用延迟扩展。您还需要处理您要删除的路径位于%path% 末尾的可能性,因此不会被; 终止。

@echo off

set removedir=d:\bar
set PATH=c:\foo;%removedir%;y:\baz&REM Set example %path%

echo Starting with %%PATH%% set to %PATH%

setlocal enableextensions enabledelayedexpansion
set _=!PATH:%removedir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removedir%=!
endlocal & set PATH=%_%

echo %%PATH%% is now %PATH%

这里作为辅助函数:

@echo off
goto start

:removeFromPath 
echo.Debug: Starting function with remove=%~1 and %%PATH%%=%PATH%
setlocal enableextensions enabledelayedexpansion
set removedir=%~1
set _=!PATH:%removedir%;=!
if "%_%" == "%PATH%" set _=!PATH:;%removedir%=!
endlocal & set PATH=%_%
echo.Debug: Ending function with %%PATH%%=%PATH%
goto :EOF


:start
set exampleremovedir=d:\bar
set PATH=c:\foo;%exampleremovedir%;y:\baz&REM Set example %path%

echo Starting with %%PATH%% set to %PATH%

call :removeFromPath %exampleremovedir%

echo %%PATH%% is now %PATH%

【讨论】:

  • 只要我不将其限定为函数,它就可以很好地工作。如果我将函数:removeFromPath 放在我做set removedir=%~1 的位置,然后使用您的代码,即使该函数内的回显显示未更改的路径。我在这里错过了什么?
  • @Lilo 你试过setlocal enabledelayedexpansion 函数内部吗?
  • @GerhardBarnard 是的,我做到了。我看不出有什么不同,但它不起作用...... :(
  • @Anders 我注意到了,如果exampleremovedir 在路径的末尾,它会在路径的末尾留下;
  • @GerhardBarnard:谢谢,现在应该修好了
猜你喜欢
  • 2021-06-01
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-02
  • 2020-01-21
  • 1970-01-01
相关资源
最近更新 更多