I'm trying to use CMDER for a development environment that I've setup.
Basically I've created a .bat file that calls:
@ECHO OFF
start Z:\_DEV\OS_WINDOWS\9_MISC_TOOLS\CMDER\Cmder.exe
Then I've placed the file startdev.bat in: %CMDER_HOME%\config\profile.d
So everything seems to work just fine, but when the startdev.bat finishes, issuing an:
echo %PATH%
returns:
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
...any idea what's happening?
I would either expect CMDER to override PATH with the value from its own settings, or use my full path, which before the startdev.bat ends shows the value of:
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
..but the fact that it only seems to be keeping the value as defined about halfway through the batch job is strange.
Any ideas?
First I recommend opening a command prompt window and run setlocal /?
and endlocal /?
to get displayed the help/documentation for those two commands. Very important to know is that every setlocal
without a corresponding endlocal
results in an implicit execution of endlocal
by cmd.exe
before exiting processing of a batch file or a subroutine called with command CALL.
Next I suggest reading this answer for even more details about the commands SETLOCAL and ENDLOCAL and what happens on using them.
I suggest like michael_heath to change this code block:
setLocal EnableDelayedExpansion
set CLASSPATH=.
for /R %JRE_HOME%\lib %%a in (*.jar) do (
set CLASSPATH=!CLASSPATH!;%%a
)
set CLASSPATH=!CLASSPATH!
Better would be:
setLocal EnableExtensions EnableDelayedExpansion
set CLASSPATH=.
for /R "%JRE_HOME%\lib" %%a in (*.jar) do set "CLASSPATH=!CLASSPATH!;%%a"
endlocal & set "CLASSPATH=%CLASSPATH%"
Now the local environment is ended with passing the environment variable CLASSPATH
from local environment, on which it was defined, to the restored previous environment because of cmd.exe
expands %CLASSPATH%
to current value of the environment variable CLASSPATH
in current local environment before executing the command endlocal
which restores the previous environment.
Wrong in your batch file is also set WINDIR=%SystemRoot%;%SystemRoot%
which should be set "WINDIR=%SystemRoot%"
.
I recommend further reading 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 including USERNAME
and USERPROFILE
and so is written safe for most environment variable definitions.
This code block is also not optimal:
FOR /F "usebackq" %%i IN (`hostname`) DO SET HOSTNAME=%%i
echo Running on hostname: %HOSTNAME%
The host name respectively computer name could contain also a space or characters critical for command line or start with a semicolon for some unknown reason. So better would be:
FOR /F delims^=^ eol^= %%i IN ('hostname') DO SET "HOSTNAME=%%i"
setlocal EnableDelayedExpansion & echo Running on host name: !HOSTNAME!& endlocal
Whereby there is the environment variable COMPUTERNAME
predefined by Windows making it possible to use just following command line:
setlocal EnableDelayedExpansion & echo Running on host name: !ComputerName!& endlocal
An ECHO command line containing an immediately expanded environment variable reference on which it is unknown if its value contains &|<>
is always a problem because of the environment variable reference is expanded before further processing of the command line by cmd.exe
as described at How does the Windows Command Interpreter (CMD.EXE) parse scripts?
I suggest also reading DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ and avoid the usage of echo.
in the batch file to output an empty line.