运行daemonized脚本的Java执行Bash脚本

运行daemonized脚本的Java执行Bash脚本,java,linux,bash,Java,Linux,Bash,我正在编写一个bash脚本,该脚本在我的Java服务器应用程序请求服务器重新启动时运行。此脚本执行需要在Java应用程序的进程树之外的操作 我使用ProcessBuilder以以下方式调用Java中的重启脚本: // Vars declared at the top of the file private static final String LOC = "/some/directory/"; private static final String RESTART_SCRIPT = LOC +

我正在编写一个bash脚本,该脚本在我的Java服务器应用程序请求服务器重新启动时运行。此脚本执行需要在Java应用程序的进程树之外的操作

我使用ProcessBuilder以以下方式调用Java中的重启脚本:

// Vars declared at the top of the file
private static final String LOC = "/some/directory/";
private static final String RESTART_SCRIPT = LOC + "restart.sh";
...
// In the function that is invoked to handle reboot behavior
final ProcessBuilder pb = new ProcessBuilder(RESTART_SCRIPT);
Process p = pb.start();
此脚本执行以下操作来解除处理所有重新启动逻辑的另一个脚本的监视。如下所示:

#!/bin/bash
(bash /some/directory/shutdownHandler.sh "true" &)
exit 0
在Java应用程序中,调用包含ProcessBuilder逻辑的函数时,在shutdownHandler.sh脚本中看不到该逻辑的效果。即使是简单的文本回显到文件中也不会发生。我已经检查了我是否有正确的权限

当我直接从命令行执行restart.sh时,它会按预期工作


请就我为什么会看到这种行为差异提出建议。Java有没有办法杀死守护脚本?

我建议您尝试以下简化:

final String[] RESTART_COMMAND = { "nohup", "/some/directory/shutdownHandler.sh", "true" };
final ProcessBuilder pb = new ProcessBuilder(RESTART_COMMAND);
Process p = pb.start();
//DON'T waitFor()

使用
nohup
和避免使用
waitFor
应该具有与您的
RESTART\u脚本实现相同的效果:两个进程的生命周期都是独立的(jvm不会等待
shutdownHandler.sh
,Java进程的终止不会导致
shutdownHandler.sh
的中断).

我找到了一种方法,可以在我描述的使用场景中正确触发脚本
shutdownHandler.sh
。问题在于如何对
shutdownHandler.sh
进行后台监控。我已将
restart.sh
更改为:

#!/bin/bash
LOGFILE="/some/log/directory/scriptLog.log"
(setsid /some/directory/shutdownHandler.sh "true" >$LOGFILE 2>&1 < /dev/null &)
exit 0
!/bin/bash
LOGFILE=“/some/log/directory/scriptLog.log”
(setsid/some/directory/shutdownHandler.sh“true”>$LOGFILE 2>&1
上面提到了一些关键的事情:

  • 处理脚本的
    stdout
    stderr
    stdin
    stdout
    stderr
    被引导到
    LOGFILE
    并将
    dev/null
    附加到
    stdin
  • 断开与控制tty的连接
  • 重新将脚本复制到init。
    shutdownHandler.sh
    将不会与JVM位于同一进程树中

您是否尝试过以脚本作为参数运行bash?您是否指的是Java ProcessBuilder部分?如果是,restart.sh脚本确实包含一行shebang(我刚刚编辑了要包含的问题)。这应该意味着使用shebang中的解释器调用脚本,并将脚本作为第一个参数。我不确定Java是否尊重shebang,因此显式设置shell可能会解决此问题。我不确定Java是否能够终止daemonized进程,但您可以尝试使用
nohup
nohup bash/som调用它吗e/directory/shutdownHandler.sh“true”和