我想杀死整个进程树。使用通用脚本语言实现这一目标的最佳方法是什么?我在寻找一个简单的解决办法。
当前回答
输入ps -ef检查进程id。 通过输入Kill -9 <pid>来终止进程
其他回答
根据志刚的回答,这可以避免自我毁灭:
init_killtree() {
local pid=$1 child
for child in $(pgrep -P $pid); do
init_killtree $child
done
[ $pid -ne $$ ] && kill -kill $pid
}
在shell脚本中杀死子进程:
很多时候我们需要杀死因为某些原因被挂起或阻塞的子进程。如。FTP连接问题。
有两种方法,
1)为每个子进程创建独立的新父进程,该父进程将在超时时监视并终止子进程。
创建test.sh,如下所示:
#!/bin/bash
declare -a CMDs=("AAA" "BBB" "CCC" "DDD")
for CMD in ${CMDs[*]}; do
(sleep 10 & PID=$!; echo "Started $CMD => $PID"; sleep 5; echo "Killing $CMD => $PID"; kill $PID; echo "$CMD Completed.") &
done
exit;
使用以下命令查看其他终端中名称为“test”的进程。
watch -n1 'ps x -o "%p %r %c" | grep "test" '
上面的脚本将创建4个新的子进程和它们的父进程。每个子进程将运行10秒。但是一旦达到5秒的超时,它们各自的父进程将终止这些子进程。 所以孩子将无法完成执行(10秒)。 围绕这些时间(切换10和5)来玩游戏,看看另一种行为。在这种情况下,child将在达到10秒超时之前在5秒内完成执行。
2)让当前父进程监视并在超时时终止子进程。这不会创建单独的父节点来监视每个子节点。此外,您还可以在同一个父进程中正确地管理所有子进程。
创建test.sh,如下所示:
#!/bin/bash
declare -A CPIDs;
declare -a CMDs=("AAA" "BBB" "CCC" "DDD")
CMD_TIME=15;
for CMD in ${CMDs[*]}; do
(echo "Started..$CMD"; sleep $CMD_TIME; echo "$CMD Done";) &
CPIDs[$!]="$RN";
sleep 1;
done
GPID=$(ps -o pgid= $$);
CNT_TIME_OUT=10;
CNT=0;
while (true); do
declare -A TMP_CPIDs;
for PID in "${!CPIDs[@]}"; do
echo "Checking "${CPIDs[$PID]}"=>"$PID;
if ps -p $PID > /dev/null ; then
echo "-->"${CPIDs[$PID]}"=>"$PID" is running..";
TMP_CPIDs[$PID]=${CPIDs[$PID]};
else
echo "-->"${CPIDs[$PID]}"=>"$PID" is completed.";
fi
done
if [ ${#TMP_CPIDs[@]} == 0 ]; then
echo "All commands completed.";
break;
else
unset CPIDs;
declare -A CPIDs;
for PID in "${!TMP_CPIDs[@]}"; do
CPIDs[$PID]=${TMP_CPIDs[$PID]};
done
unset TMP_CPIDs;
if [ $CNT -gt $CNT_TIME_OUT ]; then
echo ${CPIDs[@]}"PIDs not reponding. Timeout reached $CNT sec. killing all childern with GPID $GPID..";
kill -- -$GPID;
fi
fi
CNT=$((CNT+1));
echo "waiting since $b secs..";
sleep 1;
done
exit;
使用以下命令查看其他终端中名称为“test”的进程。
watch -n1 'ps x -o "%p %r %c" | grep "test" '
Above script will create 4 new child processes. We are storing pids of all child process and looping over them to check if they are finished their execution or still running. Child process will execution till CMD_TIME time. But if CNT_TIME_OUT timeout reach , All children will get killed by parent process. You can switch timing and play around with script to see behavior. One drawback of this approach is , it is using group id for killing all child tree. But parent process itself belong to same group so it will also get killed.
如果不希望终止父进程,可能需要为父进程分配其他组id。
更多细节可以在这里找到,
在shell脚本中杀死子进程
我不能评论(没有足够的声誉),所以我被迫添加一个新的答案,即使这不是一个真正的答案。
@olibre在2月28日给出了一个非常好的、彻底的回答,但有一个小问题。ps opgid= $PID的输出将包含小于5位的PID的前导空格,因为ps正在对列进行对齐(将数字右对齐)。在整个命令行中,这会导致一个负号,后面跟着空格(s),然后是组PID。简单的解决方案是通过管道将ps传送到tr以删除空格:
kill -- -$( ps opgid= $PID | tr -d ' ' )
下面的shell函数与许多其他答案类似,但它在Linux和BSD (OS X等)上都可以工作,没有像pgrep这样的外部依赖:
killtree() {
local parent=$1 child
for child in $(ps -o ppid= -o pid= | awk "\$1==$parent {print \$2}"); do
killtree $child
done
kill $parent
}
如果你的系统上有pstrree和perl,你可以尝试这样做:
perl -e 'kill 9, (`pstree -p PID` =~ m/\((\d+)\)/sg)'
推荐文章
- 理解PrimeFaces处理/更新和JSF f:ajax执行/呈现属性
- 我可以在/etc/hosts中映射主机名*和端口*吗?
- Tar归档,从文件列表中获取输入
- 寻找不属于特定用户的文件
- 如何使用gnu cp命令将一个文件复制到多个目录
- 守护进程的错误响应:已被集装箱使用"
- 使用gcc命令行从.c文件构建.so文件
- bash中的字符串比较。[[:没有找到
- 如何在Bash脚本中使用密码执行sftp命令?
- 在Bash中将命令行参数转换为数组
- 为什么用反斜杠开始shell命令?
- 如何找到Java堆大小和内存使用(Linux)?
- 遍历带空格的文件列表
- 在Bash中检查传递的参数是否为文件或目录
- Bash:无限睡眠(无限阻塞)