Как предотвратить сигнал SIGINT убивает подпроцессы в Java - PullRequest
0 голосов
/ 26 мая 2019

Я использую Java exec для запуска bash-скрипта, но когда я ввожу CTRL + C, процесс Java завершится, а также подпроцессы, как я могу сохранить выполнение дочерних процессов после завершения работы JVM?

String command = "ffmpeg -re -strict -2 -i video.mp4 -c:v copy -an -f rtp rtp://127.0.0.1:1234";
Utils.writeToFile("sub.sh", command);

new ProcessBuilder("parent.sh", "sub.sh").inheritIO()
        .start().waitFor();

parent.sh:

#!/bin/bash
trap '' SIGINT SIGTERM SIGQUIT SIGHUP SIGTSTP
nohup "$@" &

Я прочитал ответы на похожие вопросы здесь и здесь , например, запустить родительский сценарий bash в этомСценарий запуска команды с использованием nohup или команды trap для предотвращения сигналов, по моим исследованиям, он работает, например, "tail -f somefile", но не для моего варианта использования "ffmpeg -params", пожалуйста, помогите, спасибо.

1 Ответ

2 голосов
/ 26 мая 2019

TL; DR

Используйте setsid вместо nohup в вашем parent.sh:

#!/bin/bash
setsid $@ &

Первая проблема заключается вваша Java-программа получает сигнал SIGTERM (после CTRL + C), JVM отправляет сигнал SIGKILL дочерним процессам, который не может быть перехвачен, заблокирован или проигнорирован.Итак, как только ваш parent.sh процесс получает SIGKILL, он передается дочернему процессу sub.sh, который останавливает процесс.

Вторая проблема связана с nohup "$@" &, когда ваша дочерняя программа sub.sh запускается в фоновом режиме, но она не полностью отсоединена от текущего терминала.nohup в основном игнорирует сигнал SIGHUP.Он выполняет процесс нормально (в фоновом режиме) и фактически не обеспечивает демонизацию.

Вместо nohup, вы можете использовать setsid , который отсоединяет дочерний процесс sub.sh отсоздание нового сеанса, который затем не будет иметь управляющего терминала и, следовательно, не получит сигнал SIGKILL.

Еще один способ сделать это может использовать disown, напримерsource $@ & disown, но в этом случае он не заблокирует текущий терминал, на котором работает parent.sh.Проблема в том, что вы не сможете узнать, когда завершится дочерний процесс.Таким образом, у вас будет больше работы, чтобы отслеживать идентификатор дочернего процесса.

Дополнительные примечания:

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