使用 CMDER,设置 PATH 的问题

Using CMDER, issue with setting PATH

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

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

@ECHO OFF 
start Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CMDER\Cmder.exe

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

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

echo %PATH%

returns:

Z:\_DEV\OS_WINDOWS_COMPILER\JDK\ORACLE.8.0_181\bin;Z:\_DEV\OS_CYGWIN\bin;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CLutils;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\PUTTY;Z:\_DEV\OS_WINDOWS_VERSION_CONTROL\PortableGit\bin;C:\WINDOWS;C:\WINDOWS\SysWOW64;C:\WINDOWS\System32

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

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

PATH=Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CMDER\vendor\conemu-maximus5;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CMDER\vendor\conemu-maximus5\ConEmu;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CMDER\vendor\conemu-maximus5\ConEmu\Scripts;Z:\_DEV\OS_ALL\JVM_BUILD_TOOLS\GRADLE.4\bin;Z:\_DEV\OS_ALL\JVM_BUILD_TOOLS\MAVEN.5.4\bin;Z:\_DEV\OS_ALL\JVM_BUILD_TOOLS\ANT.10.5\bin;Z:\_DEV\OS_WINDOWS_BUILD_TOOLS\NODE\LTS.15.3;Z:\_DEV\OS_WINDOWS_BUILD_TOOLS\NODE\LTS.15.3\node_modules;Z:\_DEV\OS_WINDOWS_COMPILER\GO.12.4\bin;Z:\_DEV\OS_WINDOWS_COMPILER\PYTHONbit.7.13;Z:\_DEV\OS_WINDOWS_COMPILER\PYTHONbit.7.13\scripts;Z:\_DEV\OS_WINDOWS_COMPILER\ANDROID\android-sdk-windows\platform-tools;Z:\_DEV\OS_WINDOWS_COMPILER\JDK\ORACLE.8.0_181\bin;Z:\_DEV\OS_CYGWIN\bin;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\CLutils;Z:\_DEV\OS_WINDOWS_MISC_TOOLS\PUTTY;Z:\_DEV\OS_WINDOWS_VERSION_CONTROL\PortableGit\bin;C:\WINDOWS;C:\WINDOWS\SysWOW64;C:\WINDOWS\System32

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

有什么想法吗?

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

要解决此问题,请使用 endLocalset 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 变量再次作为 global

首先,我建议打开命令提示符 window 和 运行 setlocal /?endlocal /? 以显示这两个命令的 help/documentation。非常重要的是要知道,每个 setlocal 没有相应的 endlocal 都会导致 cmd.exe 在退出处理批处理文件或使用命令调用的子例程之前隐式执行 endlocal 呼叫.

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

我建议 更改此代码块:

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%"

现在,由于 cmd.exe%CLASSPATH% 扩展为在执行恢复先前环境的命令endlocal之前,当前本地环境中环境变量CLASSPATH的当前值。

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

我建议进一步阅读 Why is no string output with 'echo %var%' after using 'set var = text' on command line? It explains why the syntax set "variable=string value" is recommended nowadays. Many of the environment variable definitions use directly or indirectly %UserProfile% which means depending on whatever the user currently running the batch file has entered as user name on creation of the user account. I have seen users entering their name containing a space and non ASCII characters. And I have seen users creating an account with a user name containing character & like Company GmbH & Co. An ampersand outside a double quoted argument string is interpreted as AND operator and cmd.exe tries to execute after set also the remaining string after & as command line on using something like set USERHOME=%DEVHOME%\%USERNAME% instead of set "USERHOME=%DEVHOME%\%USERNAME%". Well, startdev.bat redefines nearly all predefined Windows Environment Variables,包括 USERNAMEUSERPROFILE,因此对于大多数环境变量定义来说都是安全的。

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

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

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

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 命令行包含一个立即扩展的环境变量引用,不知道它的值是否包含 &|<> 因为环境变量引用总是一个问题如 How does the Windows Command Interpreter (CMD.EXE) parse scripts?

所述,在进一步处理命令行之前由 cmd.exe 展开

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