我正在键入一个小的bash脚本,它应该克隆一个git存储库,签出一个特定的硬编码分支并监听一些新的提交.如果发现新的提交,脚本应该杀死正在运行的'MyApp'实例,执行git pull并最终使用gradle构建它.它也应该再次通过gradle开始.
是的,它是一个带有gradle构建文件的java应用程序.
这是我的代码:
##!/bin/bash
# GitHub Repository and Paths
GLOBAL_REPOSITORY="..."
LOCAL_REPOSITORY="..."
# Go to the repository
cd $LOCAL_REPOSITORY
# Clone the git repository if not already done
if [ ! -d "$LOCAL_REPOSITORY/.git" ]
then
git clone $GLOBAL_REPOSITORY $LOCAL_REPOSITORY
git checkout dev
fi
# Pull and build if there are new commits
LAST_GLOBAL_COMMIT=""
LAST_LOCAL_COMMIT=""
CHILDS_PID=""
while true; do
git fetch origin
LAST_GLOBAL_COMMIT="$(git rev-parse origin/dev)"
LAST_LOCAL_COMMIT="$(git rev-parse dev)"
if [ "$LAST_GLOBAL_COMMIT" != "$LAST_LOCAL_COMMIT" ]
then
if [ "$CHILDS_PID != "" ]
then
kill 9 "$CHILDS_PID" # Line 33
fi
LAST_LOCAL_COMMIT="$LAST_GLOBAL_COMMIT"
git pull origin dev
gradle
CHILDS_PID="$(gnome-terminal -e \"gradle run\" & echo $!)"
fi
sleep 300
done
发生的问题是子终端和MyApp仍在运行.只有gradle似乎死了.但我想杀死所有子进程,然后再次运行它们.只有运行我脚本的终端才不会被杀死.
在实际情况中,进程树应如下所示:
Main Terminal (Running the script)
|
|
Child Terminal
|
|
Gradle run
|
|
MyApplication
我的问题是除了第33行顶部的终端之外,我怎样才能立刻杀死所有这些进程?
编辑:
这里的不同之处在于我搜索了一种方法来查找子树的主节点并在第二步中将其终止.
但我发现如果一个bash实例正在调用gnome-terminal或任何其他终端或tty它正在进行一个初始化分叉终端的进程.
因此,例如,terminal_1的PID为42,并且我通过它启动另一个终端,然后它将启动一个PID为43的init进程,该进程将初始化将具有PID为44的terminal_2.但是terminal_1仅获得43作为回报价值.在此之后,init进程终止,如果你试图杀死PID 43,它逻辑上说没有那个PID的进程.
在这一点上跟踪是不可能的,我通过编写自己使用fork的ac程序解决了我的问题.