Ссылка на аргумент пакетного файла
Открыть окно командной строки и запустить call /?
.Справка по выводу объясняет, как ссылаться на аргументы пакетного файла.%1
ссылается на первый аргумент, переданный в командный файл.Это может быть, например, 1
(не строка аргумента в кавычках), но также "1"
(строка аргумента в кавычках).%~1
ссылается на первую строку аргумента с удалением окружающих двойных кавычек.
Неправильно добавлять еще одну %
после ссылки на аргумент.Синтаксис %variable%
используется для ссылки на строковое значение переменной среды.На аргументы пакетного файла ссылаются только со знаком процента и цифрой без или с модификатором между.После цифры больше нет знака процента.Это также причина, по которой 1
, 2
, 3
, ... невозможны в качестве имен для переменных среды.
Так что нехорошо это IF "%1%" == "0" (
, так как это может привести к пакетной обработкефайл, вызываемый "1"
в качестве первого аргумента при выполнении командной строки:
IF ""1"" == "0" (
Гораздо лучший синтаксис - IF "%~1" == "0" (
, что приводит к выполнению командной строки:
IF "1" == "0" (
См. Мой ответ о разнице между «…» и x «…» в пакете для получения дополнительной информации о том, как оценивать аргументы пакетного файла.
Добавление пути к папке к локальной переменной PATH
Переменная окружения PATH
содержит список разделенных запятыми путей к папкам, в котором разделитель списка - точка с запятой вместо запятой.
Следовательно, ;
в концеPATH
означает, что есть еще один путь к папке, который является пустым путем к папке.Можно указать пустой путь к папке в середине или в конце PATH
, но это плохая практика, поскольку PATH
не должно содержать пустых путей к папкам.
По этой причинеследующая командная строка в вашем коде не подходит:
if errorlevel 1 SET "PATH=%PATH%%cd%\App0;"
Также отсутствует ;
, если PATH
еще не заканчивается точкой с запятой, что может стать причиной появления сообщения об ошибке на секундувыполнение пакетного файла.
Более качественный код можно увидеть ниже на полностью пересмотренном коде пакетного файла.
Ссылка на текущий каталог
Можно сослаться на текущий каталог с помощью%CD%
, который может отличаться от каталога командных файлов, на который ссылается %~dp0
.%~dp0
ссылается на диск и путь аргумента 0, который является самим пакетным файлом.Строка пути к пакетному файлу, на которую указывает %~dp0
, всегда заканчивается обратной косой чертой.Поэтому после объединения %~dp0
после конкатенации с именем файла / папки не следует использовать дополнительную обратную косую черту.
Динамическая переменная среды CD
обычно заканчивается без обратной косой черты в конце.Таким образом, в большинстве случаев %CD%
необходимо объединить с дополнительным \
с именем файла / папки.Но есть одно исключение, которое необходимо учитывать при использовании %CD%
в командном файле: %CD%
расширяется до строки с \
в конце, а текущий каталог является корневым каталогом диска, например C:\
или D:\
.Поэтому всегда необходимо использовать %CD%
, чтобы проверить, заканчивается ли строка обратной косой чертой, прежде чем добавлять имя файла / папки без или с дополнительной обратной косой чертой.
Другие рекомендации
Использованиеследует избегать использования командного блока, начинающегося с (
и заканчивающегося )
, при использовании переменных среды, определенных / измененных в командном блоке и на которые имеются ссылки в командном блоке, поскольку для этого необходимо использовать отложенное расширение объясняется выводом справки при запуске set /?
в окне командной строки в примере IF и FOR , в которых обычно используются блоки команд.Командный процессор Windows предназначен для выполнения одной командной строки за другой.Использование командных блоков в некоторых случаях может ускорить выполнение командного файла, но во многих случаях их лучше избегать.
См. отладка командного файла с кратким описанием, как отлаживать командный файл.Одношаговое выполнение не реально возможно.Но cmd.exe
показывает, в какой строке или блоке команд произошла ошибка, приводящая к завершению выполнения пакетного файла, и что это за ошибка.
Исправленный код пакетного файла
Вот исправленный код пакетного файла:
@echo off
goto Main
:AddPath
echo %PATH%;|%SystemRoot%\System32\findstr.exe /I /C:"\%~1;" >nul 2>&1
if not errorlevel 1 echo Found %~1 in PATH& goto :EOF
set "Separator=;"
if "%PATH:~-1%" == ";" set "Separator="
if "%CD:~-1%" == "\" (set "AppPath=%CD%%~1") else set "AppPath=%CD%\%~1"
set "PATH=%PATH%%Separator%%AppPath%"
set "AppPath="
set "Separator="
goto :EOF
:Main
if "%~1" == "0" call :AddPath App0 & goto errorBypass
if "%~1" == "1" call :AddPath App1 & goto errorBypass
if not "%~1" == "" goto RunApp
if "%HUMBER_HOME%" == "" goto Error2
if exist "%HUMBER_HOME%\bin\setEnv.bat" (
call "%HUMBER_HOME%\bin\setEnv.bat"
goto errorBypass
)
echo File "setEnv.bat" in subdirectory "bin" in directory
echo defined by environment variable HUMBER_HOME not found.
echo HUMBER_HOME directory: "%HUMBER_HOME%"
echo/
pause
goto :EOF
:RunApp
echo HERE
goto :EOF
:Error2
echo Error2
goto :EOF
:errorBypass
if exist "run.bat" call "run.bat"
В верхней части пакетного файла определена подпрограмма AddPath
, что немного необычно.Таким образом, вторая строка с goto Main
приводит к перепрыгиванию кода подпрограммы при запуске выполнения командного файла.
Подпрограмма AddPath
вызывается с App0
или App1
в первом аргументебудучи 0
или "0"
или 1
или "1"
.
Первая строка в AddPath
выводит текущее значение локальной переменной среды PATH
с добавленной точкой с запятой и перенаправляет этот вывод на FINDSTR , который осуществляет поиск без учета регистра и буквально для первой строки аргумента, передаваемой подпрограмме после обратной косой черты и заканчивающейся точкой с запятой.Дополнительные \
и ;
должны избегать ложных срабатываний на любом пути к папке в PATH
, который случайно также содержит App0
или App1
где-то в середине пути к папке.Это небольшое улучшение не на 100% отказоустойчиво, но должно быть достаточно хорошим.
FINDSTR завершается с 0
для искомой строки, найденной в строке.В этом случае выводится только информационное сообщение и происходит выход из подпрограммы, что приводит к продолжению выполнения пакетного файла для основного кода, для которого подпрограмма была вызвана ранее.В противном случае переданное имя приложения должно быть добавлено к локальному PATH
.
См. Также:
Итак, сначала переменная окружения Separator
определяется со значением ;
в качестве значения.Но если локальный PATH
уже заканчивается обратной косой чертой, хотя не должен, переменная окружения немедленно удаляется.Обратите внимание, что командная строка, сравнивающая последний символ PATH
с ;
, может потерпеть неудачу, если PATH
заканчивается "
.Так что эта простая версия не на 100% отказоустойчива.
Далее текущий путь к каталогу объединяется с переданным именем папки приложения без или с дополнительной обратной косой чертой в зависимости от того, является ли текущий каталог корневым каталогом диска или подкаталогомлюбой каталог.
Затем локальный PATH
расширяется путем добавления пути к приложению в соответствии с переданным аргументом без или с дополнительной точкой с запятой перед.
Наконец, больше не нужны переменные среды Separator
и AppPath
удаляются перед выходом из подпрограммы.
Основной ошибкой в основном коде, который публикуется в вопросе, являются пропущенные знаки процента вокруг переменной среды HUMBER_HOME
при вызове пакетного файла setEnv.bat
в подкаталоге bin
каталога, назначенного переменной среды HUMBER_HOME
.Это может быть еще одной причиной сообщения об ошибке при повторном выполнении пакетного файла.
Пересмотренный код сначала проверяет, существует ли каждый вызываемый пакетный файл перед его вызовом.
Для понимания использованногоКоманды и как они работают, откройте окно командной строки, выполните там следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.
call /?
echo /?
findstr /?
goto /?
if /?
pause /?
set /?