我正在尝试将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
..但是似乎只保留批处理作业中途定义的值的事实很奇怪。
有什么想法吗?
答案 0 :(得分:0)
“ 批处理作业的一半”,因为您有
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
个变量为 global 。
答案 1 :(得分:0)
首先,我建议打开命令提示符窗口并运行setlocal /?
和endlocal /?
以显示这两个命令的帮助/文档。非常重要的一点是,在退出批处理文件或使用command调用的子例程的处理之前,每个没有相应setlocal
的{{1}}都会导致endlocal
隐式执行endlocal
致电。
接下来,我建议阅读this answer,以获得有关 SETLOCAL 和 ENDLOCAL 命令以及使用它们的操作的更多详细信息。
我建议像michael_heath一样更改此代码块:
cmd.exe
更好的是:
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%
来恢复先前的环境之前,先在当前本地环境中使用环境变量CLASSPATH
的值。
批处理文件中的错误endlocal
也应为set WINDIR=%SystemRoot%;%SystemRoot%
。
我建议进一步阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line?,它解释了为什么现在建议使用语法set "WINDIR=%SystemRoot%"
。许多环境变量定义直接或间接使用set "variable=string value"
,这意味着在创建用户帐户时,取决于当前运行批处理文件的用户作为用户名输入的内容。我看到用户输入的名称包含空格和非ASCII字符。而且我已经看到用户使用诸如%UserProfile%
之类的包含字符&
的用户名创建帐户。在双引号参数字符串外的与号被解释为 AND 运算符,并且Company GmbH & Co
尝试在cmd.exe
之后执行,并且在set
之后的其余字符串也用作使用命令行类似于&
而不是set USERHOME=%DEVHOME%\%USERNAME%
。好吧,set "USERHOME=%DEVHOME%\%USERNAME%"
重新定义了几乎所有预定义的Windows Environment Variables,包括startdev.bat
和USERNAME
,因此对于大多数环境变量定义来说都是安全的。
此代码块也不是最佳的:
USERPROFILE
主机名或计算机名可能还包含空格或对于命令行至关重要的字符,或者由于某些未知原因而以分号开头。这样更好:
FOR /F "usebackq" %%i IN (`hostname`) DO SET HOSTNAME=%%i
echo Running on hostname: %HOSTNAME%
Windows预先定义了环境变量FOR /F delims^=^ eol^= %%i IN ('hostname') DO SET "HOSTNAME=%%i"
setlocal EnableDelayedExpansion & echo Running on host name: !HOSTNAME!& endlocal
,因此可以使用以下命令行:
COMPUTERNAME
一个 ECHO 命令行包含一个立即扩展的环境变量引用,由于其环境变量引用在进行进一步处理之前已被扩展,因此未知其值是否包含setlocal EnableDelayedExpansion & echo Running on host name: !ComputerName!& endlocal
始终是一个问题&|<>
定义的命令行,如How does the Windows Command Interpreter (CMD.EXE) parse scripts?
我建议还阅读DosTips论坛主题ECHO. FAILS to give text or blank line - Instead use ECHO/,并避免在批处理文件中使用cmd.exe
来输出空行。