Linux 使用Ctrl+;从Bash脚本运行的Kill Java应用程序进程树;C

Linux 使用Ctrl+;从Bash脚本运行的Kill Java应用程序进程树;C,linux,bash,shell,unix,scripting,Linux,Bash,Shell,Unix,Scripting,我有一个脚本,它运行java应用程序并保持前台运行。 我想要实现的是在发出Ctrl+c时关闭java应用程序 假设是这样的: bash1 -> bash2 -> wrapper.jar -> myapp.jar bash-file-1: trap "stopit; exit" SIGINT echo "Going to run java app" source bash-file-2.sh bash-file-2.sh: exec java -jar myapp.jar

我有一个脚本,它运行java应用程序并保持前台运行。 我想要实现的是在发出Ctrl+c时关闭java应用程序

假设是这样的:

bash1 -> bash2 -> wrapper.jar -> myapp.jar
bash-file-1:

trap "stopit; exit" SIGINT
echo "Going to run java app"
source bash-file-2.sh
bash-file-2.sh:

exec java -jar myapp.jar
  • 函数的作用是:查找.pid文件并终止进程。在后台运行应用程序时效果良好
这里发生的是,当我发出Ctrl+c时,我退出控制台模式,但应用程序仍在后台运行。我猜这是因为“exec”命令导致应用程序在另一个shell中运行。这是正确的吗

在这种情况下,如何捕获ctrl+c并调用stopit函数

编辑

我正在运行的java应用程序是一个包装器jar,它调用实际的jar文件

应该是这样的:

bash1 -> bash2 -> wrapper.jar -> myapp.jar
如果您的子进程(Java应用程序)生成了新进程,则需要删除应用程序根目录下的完整进程树

首先,定义(通用)辅助函数:

#!/bin/bash

# Prints all descendant of a process `ppid`, level-wise, bottom-up.
# Usage: _get_proc_descendants ppid
function _get_proc_descendants() {
    local pid ppid="$1"
    local children=$(ps hopid --ppid "$ppid")
    for pid in $children; do
        echo "$pid"
        _get_proc_descendants "$pid"
    done
}

# Kills all process trees rooted at each of the `pid`s given,
# along with all of their ancestors.
# Usage: killtree [pid1 pid2 ...]
function killtree() {
    while [ "$#" -gt 0 ]; do
        local pids=("$1" $(_get_proc_descendants "$1"))
        kill -TERM "${pids[@]}" &>/dev/null
        shift
    done
}
然后,在你的
陷阱中说:

trap "killtree $java_app_pid; exit" SIGINT
其中,
$java\u app\u pid
是java应用程序的pid(您在pid文件中说过)

或者,您可以定义
killtree
仅杀死PID的后代:

function killtree() {
    while [ "$#" -gt 0 ]; do
        local pids=($(_get_proc_descendants "$1"))
        kill -TERM "${pids[@]}" &>/dev/null
        shift
    done
}
并简化您的
陷阱
(杀死脚本的子脚本):


exec
用另一个进程替换您的进程,
stopit
将不再存在于该进程中,但您可能并不真正需要
exec
您只需使用
java…
即可,它将像您键入命令一样执行该命令it@EricRenouf我编辑了这个问题,,我试过你所说的,并意识到问题来自一个jar调用另一个jar。可能吧?调用是怎么发生的,我是说第二个罐子