【问题标题】:How to search and replace a string in environment variable PATH?如何在环境变量 PATH 中搜索和替换字符串?
【发布时间】:2014-07-09 08:04:24
【问题描述】:

是否有任何命令可以批量搜索和替换环境变量PATH中的字符串?

例如环境变量PATH的内容为:

C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\AccuRev\bin;C:\Python24

我必须在这个变量中搜索C:\Python24,并需要将其替换为C:\Python27

【问题讨论】:

  • 语法为%PATH:Python24=Python27%(使用set/setx 保存更改的变量)。请阅读set 语法帮助。 (评论已经回答了很多次了……先搜索一下!)
  • 如果我在命令提示符中使用“set path=%path:C:\Python24=C:\Python27%”,则表明替换已正确完成。但此更改在 Control Panel\System 和 Security\System\ 的 Path 变量中不可见

标签: batch-file search replace command


【解决方案1】:

本地路径替换

wmz提供的解决方案很完美:

set "PATH=%PATH:Python24=Python27%"

有关替换环境变量值的详细信息,请在命令提示符窗口 set /? 中运行,或查看 Windows 命令 set 的 Microsoft 文档页面。

Windows 在创建新进程(如运行批处理文件的 Windows 命令处理器进程)时创建父进程的环境变量表的副本(Windows 资源管理器作为桌面)。对环境变量表所做的每一次修改都只应用在这个副本上,从而避免了对其他已经运行的应用程序的影响。只有从此进程调用的应用程序才能获得修改后的环境变量表(作为新进程启动时的副本)。


系统路径替换

设置或更改系统范围内的变量的解决方案是使用命令setx(设置扩展)。

问题How to use setx command in a windows batch file的要求差不多:
如何在系统范围内替换环境变量PATH中的Python版本?

微软在参考页面上写了关于命令setx

Setx 将变量写入注册表中的主环境。使用 setx 变量设置的变量只能在未来的命令窗口中使用,而不是在当前的命令窗口中。

这意味着如果 Python 脚本在使用 setx 后从同一控制台窗口执行,则还必须使用命令 set 修改本地 PATH。已经在使用setx 更改目录列表的其他控制台或GUI 进程的环境变量PATH 的其他实例未被setx 修改。必须终止并重新启动这些进程以记录对主环境表所做的更改。

但是,如果 PATH 变量的更改应该在系统范围内完成,并且只在本地计算机上永久完成一次,通常通过 控制面板 - 系统 更容易做到这一点strong> 比从命令行使用命令setx 来做。


本地和系统路径替换示例

这是一个如何在本地和系统环境变量 PATH 中替换 Python 版本的示例。作为一项额外功能,如果 PATH 中缺少 Python 目录的路径,则会附加该路径。

@echo off

rem Replace Python24 by Python27 in local environment variable PATH.
set "NEWPATH=%PATH:Python24=Python27%"

rem Append C:\Python27 to PATH if not containing C:\Python27 at all.
if "%NEWPATH:Python27=%" == "%PATH%" set "NEWPATH=%PATH%;C:\Python27"

rem Update PATH in system environment table.
%SystemRoot%\System32\setx.exe PATH "%NEWPATH%" /M

rem Update local PATH in this console window. (Important: No double quotes!)
path %NEWPATH%

rem Remove local environment variable NEWPATH as not needed anymore.
set NEWPATH=

rem Output value of local environment variable PATH.
path

延迟扩展的替代代码:

@echo off
setlocal EnableDelayedExpansion

rem Replace Python24 by Python27 in local environment variable PATH.
set "NEWPATH=!PATH:Python24=Python27!"

rem Append C:\Python27 to PATH if not containing C:\Python27 at all.
if "!NEWPATH:Python27=!" == "!PATH!" set "NEWPATH=!PATH!;C:\Python27"

rem Update PATH in system environment table.
%SystemRoot%\System32\setx.exe PATH "!NEWPATH!" /M

rem Update local PATH in this console window. (Important: No double quotes!)
endlocal & path %NEWPATH%

rem Output value of local environment variable PATH.
path

请注意,PATH 不仅是一个环境变量,还是一个内部命令。在命令提示符窗口中输入help pathpath /? 以获取有关显示的这个小命令的简短帮助。

这里使用命令pathpath %NEWPATH% 更新环境变量PATH 的本地实例,并在最后一行显示本地环境变量PATH 中的目录示例批处理文件。

在命令setx 上,%NEWPATH% 周围的双引号非常重要,因为 PATH 很可能还包含一个或多个目录路径,其中包含一个空格。因此应该分配给系统环境变量PATH的整个字符串必须用双引号引起来。

但是命令path 要求带有目录路径的字符串始终不包含双引号,即使字符串中包含空格字符,仅仅是因为此命令不期望或不支持目录路径列表之外的其他选项(以及开发人员为命令path 编写的代码很可能没有考虑删除字符串开头和结尾的双引号,如果用户像往常一样将字符串括在几乎所有其他带双引号的命令中)。

上述批处理文件的缺点是:

  1. 本地 PATH 包含的目录始终包含所有已展开的环境变量,因此系统 PATH 不再具有例如 %SystemRoot% 的目录列表。

  2. 在当前命令进程或任何父进程中添加到本地 PATH 的其他目录也将添加到系统 PATH

在回答中解释了更新系统 PATH 的更好解决方案

Why are other folder paths also added to system PATH with SetX and not only the specified folder path?

因此,在本地和系统 PATH 中将 Python24 替换为 Python27 的更好批处理代码是:

@echo off
setlocal EnableExtensions EnableDelayedExpansion

rem Define a variable Separator with a semicolon as value if
rem the local PATH string does not end already with a semicolon.
set "Separator="
if not "!PATH:~-1!" == ";" set "Separator=;"

rem Replace Python24 by Python27 in local environment variable PATH.
set "LocalPath=!PATH:Python24=Python27!"

rem Append C:\Python27 to local PATH if not containing C:\Python27 at all.
if "!LocalPath:Python27=!" == "!PATH!" set "LocalPath=!PATH!%Separator%C:\Python27"

rem Update local PATH for this command process in this console window.
endlocal & set "PATH=%LocalPath%"

rem Output value of local environment variable PATH.
path

rem Get system PATH directly from Windows registry to get
rem the directory list with not expanded environment variables.
for /F "skip=2 tokens=1,2*" %%N in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do (
    if /I "%%N" == "Path" (
        set "SystemPath=%%P"
        if defined SystemPath goto CheckPath
    )
)
echo Error: System environment variable PATH not found with a non-empty value.
echo/
pause
goto :EOF

:CheckPath
setlocal EnableExtensions EnableDelayedExpansion
rem Define a variable Separator with a semicolon as value if
rem the system PATH string does not end already with a semicolon.
set "Separator="
if not "!SystemPath:~-1!" == ";" set "Separator=;"

rem Replace Python24 by Python27 in system environment variable PATH.
set "NewPath=!SystemPath:Python24=Python27!"

rem Append C:\Python27 to system PATH if not containing C:\Python27 at all.
if "!NewPath:Python27=!" == "!SystemPath!" set "NewPath=!SystemPath!%Separator%C:\Python27"

rem Update system PATH if any change is necessary at all. Command SETX
rem is by default not installed on Windows XP and truncates string values
rem longer than 1024 characters to 1024 characters. So command REG is used
rem to update system PATH in Windows registry if SETX is not available or
rem new system PATH is too long. Administrator privileges are requirend in
rem any case for updating persistent stored system PATH in Windows registry.
if not "!SystemPath!" == "!NewPath!" (
    set "UseSetx=1"
    if not "!NewPath:~1024,1!" == "" set "UseSetx="
    if not exist %SystemRoot%\System32\setx.exe set "UseSetx="
    if defined UseSetx (
        %SystemRoot%\System32\setx.exe Path "!NewPath!" /M >nul
    ) else (
        set "ValueType=REG_EXPAND_SZ"
        if "!NewPath:%%=!" == "!NewPath!" set "ValueType=REG_SZ"
        %SystemRoot%\System32\reg.exe ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /f /v Path /t !ValueType! /d "!NewPath!" >nul
    )
)

rem Output value of system environment variable PATH.
echo PATH=!NewPath!

endlocal

要了解所使用的命令及其工作原理,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • path /?
  • pause /?
  • rem /?
  • reg add /?
  • reg query /?
  • set /?
  • setlocal /?
  • setx /?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多