在Java中启动Shell脚本并在退出时销毁所有进程

唐汉斯·丹普夫

我需要某种特殊的设置来控制LED墙。可悲的是,我不能真正改变我使用的编程语言。我的设置如下所示:

引导过程之后,开始处理(一些疯狂的Java fork ...)。处理草图会扫描文件夹中的子文件夹(可以启动其他草图并控制LED墙)并启动Web服务器。服务器将显示所有扫描文件夹的列表。在单击上,“ Web服务器”将通过ProcessBuilder启动选定的草图。处理草图如下所示:

import http.*;
import java.util.*;
import java.lang.*;

SimpleHTTPServer server;
String prog = "";
int ExitValue = 1;
ProcessBuilder preparedsketch;
Process runningsketch;

void setup() {
  SimpleHTTPServer.useIndexHtml = false;
  server = new SimpleHTTPServer(this);
  TemplateFileHandler templateHandler = new ResultFiles("index.ftl");
  server.createContext("", templateHandler);
}


class ResultFiles extends TemplateFileHandler {
  public ResultFiles(String templateFileName) {
    super(templateFileName);
  }
  void createMap() {
    Map<String, String> params = queryToMap();
    if (params.containsKey("prog")) {
      if (params.get("prog").equals(prog)) {
        println("Has not changed");
      } else {
        println("PrevProcess: " + runningsketch);
        if (runningsketch != null) {
          println("Killing: " + runningsketch);
          runningsketch.destroy();
        }
        prog = params.get("prog");
        try {
          runningsketch = new ProcessBuilder("/Users/kessleml/dev/pixelpusher/base/processing-quit.sh", "--sketch=/Users/kessleml/dev/pixelpusher/base/sketches/pixelpusher_colourcycle_halloween", "--run").start();
          // runningsketch = new ProcessBuilder("/usr/local/bin/processing-java", "--force", "--sketch=" + sketchPath("sketches/" + prog + "/"), "--no-java", "--run").start();
        } catch (IOException ex) {
          println(ex);
        }
        println("ProjChagned: " + prog);
        println("NewProcess: " + runningsketch);
      }
    }

    File files = new File(sketchPath("sketches"));
    String[] fileslist = files.list();
    addVariable("files", fileslist);
    addVariable("selectedprog", prog);
  }
}

到现在为止一切正常。但是,如果我进行更改(当然,请单击网站上的另一个草图),我当然想关闭一个正在运行的(和循环的)草图。问题是:

当我通过runninngsketch = new ProcessBuilder("Path/To/ProcessingCLI", "--sketch=Path/To/Selected/Sketch", "--run").start();多个过程启动选定的草图时造成这种情况的原因是ProcessingCLI文件:

#!/bin/sh

# Prevents processing-java from stealing focus, see:
# https://github.com/processing/processing/issues/3996.
OPTION_FOR_HEADLESS_RUN=""
for ARG in "$@"
do
    if [ "$ARG" = "--build" ]; then
        OPTION_FOR_HEADLESS_RUN="-Djava.awt.headless=true"
    fi
done

cd "/Applications/Processing.app/Contents/Java" && /Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true $OPTION_FOR_HEADLESS_RUN -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$@"

因此,ProcessBuilder启动了三个进程:一个sh进程,它启动两个Java-Children-Processs。当我使用runningsketch.destroy()它只会杀死sh进程。这两个Java进程继续运行。由于我是在MacOS Yosemite上进行开发的,因此不知道这是否也是由于以下错误引起的:http : //bugs.java.com/bugdatabase/view_bug.do? bug_id=4770092。最终产品应在Linux机器上运行。)

我的解决方案是编写一个新的sh脚本,该脚本通过以下方式杀死所有子进程trap

#!/bin/sh

OPTION_FOR_HEADLESS_RUN=""

function killAllChildren {
    kill -9 -$(ps -o pgid= $$ | grep -o '[0-9]*')
}

trap killAllChildren SIGTERM SIGKILL
# trap "trap - SIGTERM && kill -- $$" SIGINT SIGTERM EXIT

cd "/Applications/Processing.app/Contents/Java"

/Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true $OPTION_FOR_HEADLESS_RUN -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$@"

但是不知何故,这也不起作用。即使启动了新的sh脚本并向启动的sh进程发送了例如SIGTERM,也不会破坏两个Java进程,也不会破坏sh进程。

唐汉斯·丹普夫

我找到了解决方案:

Java发送SIGTERM信号,因此我不得不捕获该信号。但是java / processing文件不是问题,sh脚本没有按预期工作。

我必须将& wait添加到脚本中。否则SIGTERM不能被困住(请参阅这篇文章:https : //apple.stackexchange.com/questions/123631/why-does-a-shell-script-trapping-sigterm-work-when-run-manually-but-not- when-ru)。

同样,杀人过程也没有成功。我必须杀死所有孩子,但sh脚本本身却不是sh脚本的父进程(在此用例中是Web服务器等)。因此,我编写了一个函数来查找所有子进程并杀死它们。像这样的事情kill -9 -$(ps -o pgid= $$ | grep -o '[0-9]*')没有奏效,因为它们杀死了整棵树。最后,sh文件如下所示:

#!/bin/sh

function killAllChildren {
    getChild $$
    pkill -TERM -P $$
}

function getChild() {
    cpids=`pgrep -P $1|xargs`
    for cpid in $cpids;
    do
        kill -15 $cpid
        getChild $cpid
    done
}

trap killAllChildren SIGUSR1 SIGTERM SIGKILL EXIT

cd "/Applications/Processing.app/Contents/Java"

/Applications/Processing.app/Contents/PlugIns/jdk1.8.0_74.jdk/Contents/Home/jre/bin/java -Djna.nosys=true -cp "ant-launcher.jar:ant.jar:core.jar:jna.jar:pde.jar:core/library/core.jar:core/library/gluegen-rt-natives-linux-amd64.jar:core/library/gluegen-rt-natives-linux-armv6hf.jar:core/library/gluegen-rt-natives-linux-i586.jar:core/library/gluegen-rt-natives-macosx-universal.jar:core/library/gluegen-rt-natives-windows-amd64.jar:core/library/gluegen-rt-natives-windows-i586.jar:core/library/gluegen-rt.jar:core/library/jogl-all-natives-linux-amd64.jar:core/library/jogl-all-natives-linux-armv6hf.jar:core/library/jogl-all-natives-linux-i586.jar:core/library/jogl-all-natives-macosx-universal.jar:core/library/jogl-all-natives-windows-amd64.jar:core/library/jogl-all-natives-windows-i586.jar:core/library/jogl-all.jar:modes/java/mode/antlr.jar:modes/java/mode/classpath-explorer-1.0.jar:modes/java/mode/com.ibm.icu.jar:modes/java/mode/JavaMode.jar:modes/java/mode/jdi.jar:modes/java/mode/jdimodel.jar:modes/java/mode/jdtCompilerAdapter.jar:modes/java/mode/jsoup-1.7.1.jar:modes/java/mode/org.eclipse.core.contenttype.jar:modes/java/mode/org.eclipse.core.jobs.jar:modes/java/mode/org.eclipse.core.resources.jar:modes/java/mode/org.eclipse.core.runtime.jar:modes/java/mode/org.eclipse.equinox.common.jar:modes/java/mode/org.eclipse.equinox.preferences.jar:modes/java/mode/org.eclipse.jdt.core.jar:modes/java/mode/org.eclipse.osgi.jar:modes/java/mode/org.eclipse.text.jar:modes/java/mode/org.netbeans.swing.outline.jar" processing.mode.java.Commander "$@" & wait

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

进程检查失败时退出Shell脚本

来自分类Dev

启动进程并在ruby脚本退出后保持其运行

来自分类Dev

使用php启动shell脚本并退出它而不停止进程

来自分类Dev

为什么ssh等待所有启动的进程退出?

来自分类Dev

退出脚本时杀死bash脚本中的后台进程

来自分类Dev

如何检测脚本中启动的所有子进程已结束?

来自分类Dev

如何使用Ctrl + C杀死在Bash脚本中启动的所有后台进程?

来自分类Dev

使用子进程调用Shell脚本不会在Shell脚本中运行所有命令

来自分类Dev

检查从脚本并行启动的进程的退出代码

来自分类Dev

如何调用Shell脚本来启动后端Java进程?

来自分类Dev

如何调用Shell脚本来启动后端Java进程?

来自分类Dev

在Elixir中启动和销毁系统进程

来自分类Dev

启动bash子shell并在脚本中运行命令

来自分类Dev

从脚本启动后台进程,并在脚本结束时进行管理

来自分类Dev

查找所有具有N个以上进程的用户,并在shell中回显它们

来自分类Dev

Shell脚本在失败时不记录Java退出状态

来自分类Dev

Shell脚本在失败时不记录Java退出状态

来自分类Dev

在node.js中的脚本退出时已分离的子进程退出

来自分类Dev

uWSGI是否在引导时启动所有进程?

来自分类Dev

通过init.d脚本启动UWSGI时退出,退出代码为1并显示“ failed”,但进程运行正常

来自分类Dev

当所有Android组件都被销毁时,应用程序进程是否总是被杀死?

来自分类Dev

循环shell脚本中的所有参数

来自分类Dev

启动进程时,使用回调在Gulp中启动Shell进程

来自分类Dev

在shell脚本中按Control + C时如何取消进程?

来自分类Dev

在Shell脚本中按Control + C时如何取消进程?

来自分类Dev

如何使用Python退出通过GeckoDriver和Selenium启动的所有Firefox进程

来自分类Dev

如何在Expect Shell脚本中获取生成的进程的退出代码?

来自分类Dev

在执行Shell脚本时,我创建了.txt文件,并在保存脚本退出后对其进行了编辑

来自分类Dev

正确退出所有进程Erlang

Related 相关文章

  1. 1

    进程检查失败时退出Shell脚本

  2. 2

    启动进程并在ruby脚本退出后保持其运行

  3. 3

    使用php启动shell脚本并退出它而不停止进程

  4. 4

    为什么ssh等待所有启动的进程退出?

  5. 5

    退出脚本时杀死bash脚本中的后台进程

  6. 6

    如何检测脚本中启动的所有子进程已结束?

  7. 7

    如何使用Ctrl + C杀死在Bash脚本中启动的所有后台进程?

  8. 8

    使用子进程调用Shell脚本不会在Shell脚本中运行所有命令

  9. 9

    检查从脚本并行启动的进程的退出代码

  10. 10

    如何调用Shell脚本来启动后端Java进程?

  11. 11

    如何调用Shell脚本来启动后端Java进程?

  12. 12

    在Elixir中启动和销毁系统进程

  13. 13

    启动bash子shell并在脚本中运行命令

  14. 14

    从脚本启动后台进程,并在脚本结束时进行管理

  15. 15

    查找所有具有N个以上进程的用户,并在shell中回显它们

  16. 16

    Shell脚本在失败时不记录Java退出状态

  17. 17

    Shell脚本在失败时不记录Java退出状态

  18. 18

    在node.js中的脚本退出时已分离的子进程退出

  19. 19

    uWSGI是否在引导时启动所有进程?

  20. 20

    通过init.d脚本启动UWSGI时退出,退出代码为1并显示“ failed”,但进程运行正常

  21. 21

    当所有Android组件都被销毁时,应用程序进程是否总是被杀死?

  22. 22

    循环shell脚本中的所有参数

  23. 23

    启动进程时,使用回调在Gulp中启动Shell进程

  24. 24

    在shell脚本中按Control + C时如何取消进程?

  25. 25

    在Shell脚本中按Control + C时如何取消进程?

  26. 26

    如何使用Python退出通过GeckoDriver和Selenium启动的所有Firefox进程

  27. 27

    如何在Expect Shell脚本中获取生成的进程的退出代码?

  28. 28

    在执行Shell脚本时,我创建了.txt文件,并在保存脚本退出后对其进行了编辑

  29. 29

    正确退出所有进程Erlang

热门标签

归档