Как запустить Java-процесс в фоновом режиме и выйти из скрипта - PullRequest
0 голосов
/ 22 декабря 2018

Я пытаюсь преобразовать bash-скрипт в пакетный режим, но у меня возникла проблема с этой проблемой.Сценарий запускает сервер Java в фоновом режиме, ждет в течение 5 секунд, а затем завершается с кодом выхода.Но в пакетном режиме я не могу ...

runserver.sh

java -jar java_server.jar &
pid=$!
sleep 5
kill -0 $pid
cmdStatus=$?
if [ $cmdStatus -ne 0 ]
then
exit 1
fi
exit 0

runserver.bat

@echo off
set EXITCODE=0 
start /b java -jar java_server.jar
timeout /t 5
for /f "tokens=1 delims= " %%i in ('jps -m ^| findstr java_server') do set PID=%%i
IF "%PID" == "" (
set EXITCODE=1
)
EXIT EXITCODE

, но если я запускаю приведенный выше пакетный скрипт, яникогда не сможет отречься от процесса Java, и он никогда не существует

1 Ответ

0 голосов
/ 22 декабря 2018

Первая ошибка в коде пакетного файла отсутствует % в строке IF "%PID" == "", чтобы действительно сравнить значение переменной окружения PID, заключенной в двойные кавычки, со строкой "".Так правильно будет IF "%PID%" == "".Подробнее о сравнении строк см. Символ, эквивалентный NEQ, LSS, GTR и т. Д. В пакетных файлах Windows .

Вторая ошибка - не использовать два раза % в последней командной строкеEXIT EXITCODE вокруг переменной окружения EXITCODE для ссылки на ее значение, которое будет корректно записано как EXIT %EXITCODE%.

Но пакетный файл лучше записать следующим образом:

@echo off
cd /D "%~dp0"
start "" /B javaw.exe -jar "%~dp0java_server.jar"
%SystemRoot%\System32\timeout.exe /T 5 /NOBREAK >nul
jps -m 2>nul | %SystemRoot%\System32\findstr.exe /L "java_server" >nul

Пакетный файл сначала делает каталог пакетного файла текущим каталогом, поскольку java_server.jar, скорее всего, находится в каталоге пакетного файла.%~dp0 расширяется до диска и пути аргумента 0, который является командным файлом.Путь к файлу, на который ссылается %~dp0, всегда заканчивается обратной косой чертой, которая является разделителем каталогов в Windows, что следует учитывать при объединении этой строки с именем файла или папки.Команда CD завершается ошибкой только в том случае, если командный файл хранится на сетевом ресурсе, доступ к которому осуществляется с помощью UNC-пути из-за того, что Windows по умолчанию предотвращает использование каталога, на который указывает путь UNC, а не дискабуква становится текущим каталогом по причинам обратной совместимости, поскольку многие консольные приложения работают некорректно, если текущий каталог не находится на диске с буквой диска.

Команда START интерпретирует первую строку в двойных кавычках как заголовок для окна консоли, открытого при запуске консольного приложения Windows в отдельном командном процессе.В этом случае окно консоли не открывается из-за использования опции /B, хотя java.exe является консольным приложением Windows.По этой причине желательно явно указывать пустую строку с "" в качестве заголовка окна при запуске приложения с графическим интерфейсом Windows, чтобы любая другая строка аргумента с двойными кавычками не интерпретировалась как необязательный заголовок окна.

Опция /B интерпретируется как фон .Большинство людей считают, что запущенное приложение отсоединено от текущего командного процесса.Это верно для приложений с графическим интерфейсом Windows, но не для консольных приложений, таких как java.exe.Дескриптор STDIN текущего командного процесса привязан к STDIN запущенного консольного приложения.Кроме того, выходные данные дескрипторов STDOUT и STDERR запущенного приложения перенаправляются в консольное окно запущенного командного процесса, который тем не менее немедленно продолжается с выполнением пакетного сценария.Опция /B означает просто запуск консольного приложения параллельно текущему командному процессу без открытия нового окна консоли, но не при запуске приложения, полностью отсоединенного от запуска командного процесса.

Решение в этом случае довольно простоепоскольку существует также javaw.exe, версия для Windows Java для Windows, предназначенная для запуска приложения Java полностью в фоновом режиме, отделенного от запускающего его процесса.

Пакетный файл для общего использования лучше всего работает науказав все файлы с полным именем файла, что означает полный путь, имя файла и расширение файла. Java исполняемый файл может быть установлен везде, и поэтому путь к папке для этого исполняемого файла не может быть указан в командном файле.Командный процессор Windows должен найти исполняемый файл javaw в текущем каталоге или в любой папке в списке папок переменной окружения local PATH.Но по крайней мере возможно указать исполняемый файл javaw с расширением файла .exe, поскольку это расширение файла хорошо известно.

Файл JAR java_server.jar указан с полным путем при условии, что этот файлхранится в том же каталоге, что и командный файл.Каталог пакетных файлов должен быть уже текущим каталогом, поэтому %~dp0 вообще не понадобится, но указывать файл для безопасности с полным путем не имеет значения.

Далее стандартное консольное приложение Windows TIMEOUT вызывается с полным именем файла с параметрами ожидания 5 секунд без перерыва (требуется Windows 7 или более поздней версии) и перенаправлением его вывода на устройство NUL .

Я ничего не знаю о файле jps и даже не установил Java.По этой причине я предполагаю, что jps - это исполняемый файл или скрипт, расширение файла которого указано в локальная переменная среды PATHEXT и хранится в каталоге пакетного файла или в любом другом каталоге, путь которого указан в локальная переменная окружения PATH.Конечно, было бы лучше указать этот файл с расширением файла и, если возможно, также с полным путем.

Стандартный вывод jps перенаправляется на стандартный ввод стандартного консольного приложения Windows FINDSTR и вывод ошибки на устройство NUL для ее подавления.

FINDSTR выполняет поиск буквенного строкового поиска с учетом регистра для java_server на стандартном выходе jps.Вывод FINDSTR не представляет интереса и поэтому перенаправляется также на устройство NUL для его подавления.

FINDSTR выходит при включенном 0искомая строка действительно найдена и с 1 ничего не найдено.Пакетный файл должен завершиться с 1 на неудачно запускающем Java-сервере и с 0 на работающем Java-сервере.Это в точности совпадает с кодом завершения FINDSTR , поэтому больше ничего не нужно делать.

cmd.exe всегда завершает выполнение пакетного файла с последним кодом завершения, установленным приложением или командой во времявыполнение пакетного файла.Это можно проверить, закомментировав вторую командную строку с помощью rem и сохранив ее, запустив этот пакетный файл из окна командной строки и запустив следующий в окне командной строки if errorlevel 1 echo Java server not running!, что приведет к ожидаемому выводу Java server not running!.Затем rem необходимо удалить из второй командной строки командного файла перед сохранением командного файла, который снова запускается из окна командной строки.После завершения выполнения второго пакетного файла повторный запуск if errorlevel 1 echo Java server not running! не приводит к выводу, а запуск if errorlevel 0 echo Java server is running. приводит к выводу Java server is running., как и ожидалось.

Для понимания используемых команд и их работы откройте командув окне приглашения выполните следующие команды и внимательно прочитайте все страницы справки, отображаемые для каждой команды.

  • call /? ... поясняет %~dp0
  • cd /?
  • echo /?
  • findstr /?
  • if /?
  • start /?

См. Также:

...