Как перехватить СИГНАЛ в Java-приложении, инициализированном с помощью bash-скрипта - PullRequest
8 голосов
/ 10 ноября 2010

Я ловлю сигнал INT в Java, используя следующий код:

    Signal.handle(new Signal("INT"), new SignalHandler () {
        public void handle(Signal sig) {

            log.warn("Received SIGINT signal. Will teardown.");

            task.tearDown();

            // Force exit anyway
            System.exit(1);
        }
      });

Когда я использую java -jar file.jar для запуска приложения, я могу уловить сигнал, отправленный с помощью kill -INT PID.

Если я позвоню java -jar file.jar & (jvm работает в фоновом режиме), я не могу уловить сигнал, отправленный с kill -INT.

Есть идеи?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 10 ноября 2010

У меня работает.Вы уверены, что убиваете правильный пид?В Unix вы можете использовать $!, чтобы получить pid последнего запущенного вами процесса.

$ java -jar file.jar &
[1] 25573

$ kill -INT $!
Received SIGINT signal. Will teardown.

Обновление:

Если вы запускаете это в фоновом режимес помощью сценария оболочки ОС создаст новую группу процессов, которая будет защищена от генерируемых клавиатурой сигналов, таких как SIGINT.Эти сигналы могут получать только процессы, чей идентификатор группы процессов совпадает с идентификатором группы процессов текущего терминала.

Поэтому попробуйте запустить его в пределах группы процессов текущего терминала следующим образом:

. ./script.sh

Тогда вы будетевозможность отправки SIGINT.

Подробнее о контроле заданий здесь .

0 голосов
/ 10 ноября 2010

Я предполагаю, что скрипт bash игнорирует SIGINT, а дочерний объект наследует маску сигнала.

Посмотрите в скрипте bash что-то вроде этого. (Может быть больше цифр, чем просто 2.)

trap "" 2

Пустая строка заставляет оболочку установить SIG_IGN. Если вместо этого вы используете:

trap ":" 2

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

...