Остановите bash-скрипт от смерти при выходе из приложения Java / Kotlin - PullRequest
0 голосов
/ 09 октября 2018

Я запускаю bash-скрипт из Kotlin, но bash-скрипт перестает работать, как только выходит приложение Kotlin.

val pr = ProcessBuilder("/home/vlad/liq", script, input).start()

Где скрипт - это скрипт liquidsoap, а input - это параметр, который передаетсяв сценарий

Как правило, он запускает что-то вроде следующего:

./liq blah.liq http://somedomain.com:8090

liq затем выполняет сценарий liquidsoap, который является первым параметром, а затем второй параметр используется какпараметр для сценария liquidsoap.

#!/bin/bash

nohup /usr/bin/liquidsoap $1 -- $2 > /dev/null 2>&1 &

# this causes syntax error
# nohup (/usr/bin/liquidsoap $1 -- $2 > /dev/null 2>&1 &)

Это приложение Kotlin запускается через java -jar dashboard.jar, в то время как приложение работает, этот сценарий liquidsoap выполняется, как только я выхожу из приложения Kotlin с помощью Ctrl + C, тот сценарий liquidsoap также останавливается.

У меня сложилось впечатление, что nohup + & создаст новую консоль, поддерживая сценарий работающим даже после выхода из приложения Kotlin, но это не так.

Любые идеи о том, какчтобы скрипт продолжал работать даже после выхода из приложения Kotlin?

1 Ответ

0 голосов
/ 10 октября 2018

nohup + & не "порождает новую консоль".Он просто создает фоновый процесс, который игнорирует сигнал зависания.См. статью в Википедии о nohup для получения дополнительной информации.

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

Двойная вилка, предложенная Науэлем Фуйе, - хорошая идея.Пример правильного синтаксиса:

( nohup /usr/bin/liquidsoap $1 -- $2 </dev/null >/dev/null 2>&1 & )
sleep 1 # Wait to ensure that 'nohup' takes effect

</dev/null не обязательно с nohup, но я добавил его для согласованности.sleep 1 - это попытка избежать возможного состояния гонки между передним и фоновым процессами.

Если это не сработает, команда setsid, если она у вас есть, может дополнительно изолировать ребенкапроцесс от своего родителя, поместив его в отдельную группу процессов и сеанс.Пример использования:

( setsid /usr/bin/liquidsoap $1 -- $2 </dev/null >/dev/null 2>&1 & )
sleep 1 # Wait to ensure that 'setsid' takes effect

См. О написании сценария оболочки Linux для безопасного отключения программ от терминала и Разница между nohup, disown и & для получения дополнительной информации.о setsid.

Если у вас нет setsid, или это не помогает, следующий вариант - использовать демон для запуска команды (что делает его полностью не связанным с процессом, который устанавливаетэто до запуска).Традиционный способ сделать это с помощью команды at:

echo "/usr/bin/liquidsoap $1 -- $2" | at now

Для этого необходимо, чтобы демон atd работал и у вас было разрешение на использование at.См. Выполнить команду 'через 5 секунд для получения дополнительной информации о at.

Современный способ запустить процесс из демона - использовать systemd-run.См. Завершение работы, приостановка требует аутентификации, когда запланировано на , для примера использования systemd-run вместо at.

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