Используя CMDER, проблема с настройкой PATH - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь использовать 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

.. но тот факт, что он только сохраняет значение, определенное примерно в середине пакетного задания, странный.

Есть идеи?

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Сначала я рекомендую открыть окно командной строки и запустить setlocal /? и endlocal /?, чтобы отобразить справку / документацию для этих двух команд. Очень важно знать, что каждый setlocal без соответствующего endlocal приводит к неявному выполнению endlocal на cmd.exe перед выходом из обработки пакетного файла или подпрограммы, вызываемой с помощью команды CALL .

Далее я предлагаю прочитать этот ответ для получения более подробной информации о командах 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% до текущего значения переменной среды CLASSPATH в текущей локальной среде перед выполнением команды endlocal, которая восстанавливает предыдущую среду.

Неправильно в вашем пакетном файле также set WINDIR=%SystemRoot%;%SystemRoot%, который должен быть set "WINDIR=%SystemRoot%".

Рекомендую к прочтению Почему нет строкового вывода с 'echo% var%' после использования 'set var = text' в командной строке? Это объясняет, почему в наше время рекомендуется синтаксис set "variable=string value". Во многих определениях переменных среды прямо или косвенно используется %UserProfile%, что означает, что в зависимости от того, что пользователь, в данный момент использующий пакетный файл, ввел в качестве имени пользователя при создании учетной записи пользователя. Я видел пользователей, которые вводили свои имена, содержащие пробел и символы, не входящие в ASCII. И я видел пользователей, создающих учетную запись с именем пользователя, содержащим символ &, например Company GmbH & Co. Амперсанд вне строки аргумента в двойных кавычках интерпретируется как оператор AND и cmd.exe пытается выполнить после set также оставшуюся строку после & как командную строку, используя что-то вроде set USERHOME=%DEVHOME%\%USERNAME% вместо set "USERHOME=%DEVHOME%\%USERNAME%". Ну, startdev.bat переопределяет почти все предопределенные переменные среды Windows , включая 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

При этом существует переменная окружения COMPUTERNAME, предопределенная Windows, позволяющая использовать только следующую командную строку:

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

Командная строка ECHO , содержащая немедленно развернутую ссылку на переменную среды, для которой неизвестно, если ее значение содержит &|<>, всегда является проблемой, поскольку ссылка на переменную среды раскрывается до дальнейшей обработки команды строка cmd.exe, как описано в Как интерпретатор сценариев команд Windows (CMD.EXE) анализирует сценарии?

Предлагаю также прочитать тему форума DosTips ЭХО. Не удается дать текст или пустую строку. Вместо этого используйте ECHO / и избегайте использования echo. в командном файле для вывода пустой строки.

0 голосов
/ 19 апреля 2019

" на полпути через пакетное задание ", поскольку у вас есть 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 снова.

...