【问题标题】:Using CMDER, issue with setting PATH使用 CMDER,设置 PATH 时出现问题
【发布时间】:2019-04-18 21:44:21
【问题描述】:

我正在尝试将CMDER 用于我设置的开发环境。

基本上我已经创建了一个 .bat 文件,它调用:

@ECHO OFF 
start Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CMDER\Cmder.exe

然后我将文件startdev.bat 放在: %CMDER_HOME%\config\profile.d

所以一切似乎都很好,但是当 startdev.bat 完成时,发出:

echo %PATH%

返回:

Z:\_DEV\OS_WINDOWS\1_COMPILER\JDK\ORACLE\1.8.0_181\bin;Z:\_DEV\OS_CYGWIN\bin;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CLutils;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\PUTTY;Z:\_DEV\OS_WINDOWS\6_VERSION_CONTROL\PortableGit\bin;C:\WINDOWS;C:\WINDOWS\SysWOW64;C:\WINDOWS\System32

...知道发生了什么吗?

我希望 CMDER 使用它自己的设置中的值覆盖 PATH,或者使用我的完整路径,在 startdev.bat 结束之前显示以下值:

PATH=Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CMDER\vendor\conemu-maximus5;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CMDER\vendor\conemu-maximus5\ConEmu;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CMDER\vendor\conemu-maximus5\ConEmu\Scripts;Z:\_DEV\OS_ALL\JVM\3_BUILD_TOOLS\GRADLE\5.4\bin;Z:\_DEV\OS_ALL\JVM\3_BUILD_TOOLS\MAVEN\3.5.4\bin;Z:\_DEV\OS_ALL\JVM\3_BUILD_TOOLS\ANT\1.10.5\bin;Z:\_DEV\OS_WINDOWS\3_BUILD_TOOLS\NODE\LTS\10.15.3;Z:\_DEV\OS_WINDOWS\3_BUILD_TOOLS\NODE\LTS\10.15.3\node_modules;Z:\_DEV\OS_WINDOWS\1_COMPILER\GO\1.12.4\bin;Z:\_DEV\OS_WINDOWS\1_COMPILER\PYTHON\32bit\2.7.13;Z:\_DEV\OS_WINDOWS\1_COMPILER\PYTHON\32bit\2.7.13\scripts;Z:\_DEV\OS_WINDOWS\1_COMPILER\ANDROID\android-sdk-windows\platform-tools;Z:\_DEV\OS_WINDOWS\1_COMPILER\JDK\ORACLE\1.8.0_181\bin;Z:\_DEV\OS_CYGWIN\bin;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CLutils;Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\PUTTY;Z:\_DEV\OS_WINDOWS\6_VERSION_CONTROL\PortableGit\bin;C:\WINDOWS;C:\WINDOWS\SysWOW64;C:\WINDOWS\System32

..但它似乎只在批处理作业的一半左右保持定义的值这一事实很奇怪。

有什么想法吗?

【问题讨论】:

  • 可能跟系统和用户环境有关。我不明白为什么 cmder 需要 profile.d 的魔法,你可以在 ConEmu 设置中本地设置所有环境。
  • 正如@Maximus 所说,%PATH% 的值是来自用户和机器环境的联合内容。您似乎只覆盖了其中之一的内容。

标签: batch-file conemu cmder


【解决方案1】:

首先,我建议打开命令提示符窗口并运行 setlocal /? 和 endlocal /? 以显示这两个命令的帮助/文档。非常重要的一点是,没有对应的endlocal 的每个setlocal 都会导致cmd.exe 在退出处理批处理文件或使用命令CALL 调用的子例程之前隐式执行endlocal .

接下来我建议阅读this answer,了解有关命令 SETLOCAL 和 ENDLOCAL 以及使用它们会发生什么的更多详细信息。

我建议michael_heath 更改此代码块:

setLocal EnableDelayedExpansion
set CLASSPATH=.
for /R %JRE_HOME%\lib %%a in (*.jar) do (
    set CLASSPATH=!CLASSPATH!;%%a
)
set CLASSPATH=!CLASSPATH!

更好的是:

setLocal EnableExtensions EnableDelayedExpansion
set CLASSPATH=.
for /R "%JRE_HOME%\lib" %%a in (*.jar) do set "CLASSPATH=!CLASSPATH!;%%a"
endlocal & set "CLASSPATH=%CLASSPATH%"

现在本地环境结束,将环境变量CLASSPATH从定义它的本地环境传递到恢复的先前环境,因为cmd.exe将%CLASSPATH%扩展为环境变量@987654338的当前值@在当前本地环境中执行命令endlocal之前恢复之前的环境。

您的批处理文件中的错误也是set WINDIR=%SystemRoot%;%SystemRoot%,应该是set "WINDIR=%SystemRoot%"。

我建议进一步阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line? 它解释了为什么现在推荐使用语法set "variable=string value"。许多环境变量定义直接或间接使用%UserProfile%,这意味着取决于当前运行批处理文件的用户在创建用户帐户时输入的用户名。我看到用户输入的姓名包含空格和非 ASCII 字符。而且我看到用户创建一个用户名包含字符& 的帐户,例如Company GmbH & Co。双引号参数字符串之外的 & 符号被解释为 AND 运算符,cmd.exe 尝试在 set 之后执行,& 之后的剩余字符串也作为命令行使用 set USERHOME=%DEVHOME%\%USERNAME% 代替的set "USERHOME=%DEVHOME%\%USERNAME%"。好吧,startdev.bat 重新定义了几乎所有预定义的 Windows Environment Variables,包括 USERNAME 和 USERPROFILE,因此对于大多数环境变量定义来说都是安全的。

这个代码块也不是最优的:

FOR /F "usebackq" %%i IN (`hostname`) DO SET HOSTNAME=%%i
echo Running on hostname: %HOSTNAME%

主机名和计算机名也可能包含对命令行至关重要的空格或字符,或者出于某种未知原因以分号开头。所以更好的是:

FOR /F delims^=^ eol^= %%i IN ('hostname') DO SET "HOSTNAME=%%i"
setlocal EnableDelayedExpansion & echo Running on host name: !HOSTNAME!& endlocal

Windows 预定义了环境变量COMPUTERNAME,因此可以使用以下命令行:

setlocal EnableDelayedExpansion & echo Running on host name: !ComputerName!& endlocal

ECHO 命令行包含一个立即展开的环境变量引用,它的值是否包含 &|<> 是未知的,因为在进一步处理cmd.exe 的命令行,如 How does the Windows Command Interpreter (CMD.EXE) parse scripts? 所述

我建议同时阅读 DosTips 论坛主题 ECHO. FAILS to give text or blank line - Instead use ECHO/ 并避免在批处理文件中使用 echo. 来输出空行。

【讨论】:

    【解决方案2】:

    “批处理作业进行到一半”,因为您有一个 setLocal EnableDelayedExpansion 进一步设置 更改变量 PATH 或其他设置为 local 的变量。 未指定的endLocal 隐含在脚本末尾。

    要解决此问题,请使用 endLocal 和 set CLASSPATH=%CLASSPATH% 在同一解析行上将 CLASSPATH 设置为 global。

    改变这部分:

        setLocal EnableDelayedExpansion
        set CLASSPATH=.
        for /R %JRE_HOME%\lib %%a in (*.jar) do (
            set CLASSPATH=!CLASSPATH!;%%a
        )
        set CLASSPATH=!CLASSPATH!
    

    到这里:

        setLocal EnableDelayedExpansion
        set CLASSPATH=.
        for /R %JRE_HOME%\lib %%a in (*.jar) do (
            set CLASSPATH=!CLASSPATH!;%%a
        )
        endLocal & set CLASSPATH=%CLASSPATH%
    

    在更改部分之后,脚本将再次将set 变量作为全局。

    【讨论】:

    • 非常感谢!很好的信息,但由于@Mofi 更详细地介绍了我给他的答案。不过谢谢你的回答!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-17
    • 2019-07-05
    • 2012-10-10
    相关资源
    最近更新 更多