退出Java / Kotlin应用程序时,避免bash脚本死掉

时间:2018-10-09 12:47:19

标签: java linux bash kotlin

我正在从Kotlin启动bash脚本,但是一旦Kotlin应用程序退出,bash脚本就会停止运行。

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

其中脚本是液体肥皂脚本,输入是要传递到脚本中的参数

通常,它将运行以下内容:

./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脚本正在运行,一旦我用Ctrl + C退出Kotlin应用程序,该liquidsoap脚本也会停止。

给我的印象是nohup + &会产生一个新的控制台,从而即使在Kotlin应用程序退出后也能保持脚本运行,但事实并非如此。

关于我的Kotlin应用程序退出后如何保持脚本运行的任何想法吗?

1 个答案:

答案 0 :(得分:1)

nohup + &不会“生成新的控制台”。它只是创建一个忽略挂断信号的后台进程。有关更多信息,请参见Wikipedia article on nohup

我不知道为什么杀死应用程序会杀死从它运行的程序,但是我可以建议一些尝试。

Nahuel Fouilleul建议的双叉是一个好主意。正确语法的一个示例是:

( 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

有关setsid的更多信息,请参见On writing a Linux shell script to safely detach programs from a terminalDifference between nohup, disown and &

如果您还没有setsid,或者它没有帮助,那么下一个选择是使用守护程序来运行命令(使其完全与将其设置为运行的过程无关) 。传统的方式是使用at命令:

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

这要求atd守护程序正在运行,并且您有权使用at。有关at的更多信息,请参见Run command 'at' 5 seconds from now

从守护程序运行进程的现代方法是使用systemd-run。有关使用systemd-run代替at的示例,请参见Shutdown, suspend require authentication when scheduled in at