Создание процесса Nohup в Java - PullRequest
       15

Создание процесса Nohup в Java

0 голосов
/ 18 сентября 2018

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

Я пытался /usr/bin/nohup commands,но это все еще, кажется, заканчивается, когда JVM, который запустил это, завершается.Есть ли способ сделать это в Java?

1 Ответ

0 голосов
/ 19 сентября 2018

Ну, во-первых, давайте напишем тестовый скрипт, который проверяет то, что вы видите:

$ cat /tmp/test.sh 
#!/bin/bash

for sig in SIGINT SIGTERM SIGHUP; do
  trap "echo Caught $sig" $sig
done

echo Traps registered, sleeping
sleep 10
echo Done sleeping, exiting

Когда я вызываю это через:

new ProcessBuilder("/tmp/test.sh").inheritIO().start().waitFor(1, TimeUnit.SECONDS);

Я вижу процесс Javaзавершается через 1 секунду (после истечения времени ожидания waitFor()), но подпроцесс продолжает работать (сообщение Done sleeping выводится на консоль после выхода из JVM).Это согласуется с тем, что обсуждалось в этом вопросе .

Итак, первое, что я бы предложил сделать, это проверить ваше первоначальное предположение о том, что подпроцесс фактически уничтожен;возможно, что-то еще идет не так, что заставляет его умереть по другой причине.Использование .inheritIO() может помочь в отладке, если подпроцесс генерирует сообщения об ошибках, которых вы не видите.


Все это говорит о том, что nohup может быть не тем, что вы хотите, а 'этим другим парнем' заметки;nohup только заставляет процесс игнорировать SIGHUP, и он все равно будет учитывать другие сигналы, в частности SIGINT и SIGTERM (Process.destroy() отправляет, например, SIGTERM).См. этот вопрос для получения дополнительной информации.

Как и во всех проблемах в программировании, введение большего количества слоев, вероятно, поможет:)

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

$ cat start-and-disconnect.sh
#!/bin/bash

# obviously tweak this as necessary to get the behavior you want,
# such as redirecting output or using disown instead of nohup
nohup "$@" & 

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

Когда вы довольны сценарием, ваш код Java просто становится:

new ProcessBuilder("/path/to/start-and-disconnect.sh", "/path/to/your_binary.sh")
    .inheritIO().start().waitFor();

Вы можете безопасно .waitFor() завершить вызов, так как start-and-disconnect.sh завершится после запускаего подпроцесс.

...