我正在使用 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/bashtrap '' SIGINT SIGTERM SIGQUIT SIGHUP SIGTSTPnohup "$@" &我已经在这里和这里阅读了类似问题的答案,例如,在该脚本运行命令中使用 nohup 启动父 bash 脚本,或使用 trap 命令来阻止信号,在我的研究中,它可以工作,例如“tail -f somefile”,但是不适用于我的用例“ffmpeg -params”,请帮忙,谢谢。
1 回答
MM们
TA贡献1886条经验 获得超2个赞
长话短说
在你的中使用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
, like source $@ & disown
,但在这种情况下,它不会阻止parent.sh
正在运行的当前终端。问题是,您无法知道子进程何时完成。因此,您将有更多工作要做,以便监视子进程 ID。
添加回答
举报
0/150
提交
取消