shell A 中调用另一个 shell B 脚本,怎么一起杀死?

我发现, 根据 shell A 的进程ID, kill 掉后, shell B 还会继续运行着.

有什么优雅的方式, 一次kill掉这种调用关系的shell呢?

阅读 4.3k
2 个回答
暂时找到一个个人认为比较靠谱的方式.
如何杀死父子进程

脚本层级调用的场景中, 传统的根据pid的方式kill, 若只是kill主脚本的进程, 所有里面调用的子脚本不会被kill. 除非获取所有子进程id, 逐个kill, 但是手动做这些, 那又累, 而且容易遗漏, 造成未知后果.

靠谱解决方案:

先学习下 pstree, awk.

调用层级: a.sh -> b.sh -> c.sh

# 启动 a.sh 后
[root@localhost ~]# ps -ef|grep a.sh|grep -v "grep"
root       2951   2772  0 17:31 pts/0    00:00:00 sh a.sh

# 查看进程树, 并切割
# -F"[()]" 指定按照正则 [()] 切割 pstree 的输出结果
# NF 内置变量, 表示按照 F 选项切割后的元素个数, 其中 $0 是原文
# $i 表示引用第 i 个元素
[root@localhost ~]# pstree -p 2951 | awk -F"[()]" '{for(i=0;i<=NF;i++)print $i}'
sh(2951)---sh(2952)---sh(2954)---sleep(2955)
sh
2951
---sh
2952
---sh
2954
---sleep
2955

上面第二行指令改进后:

pstree -p 2951 | awk -F"[()]" '{for(i=0;i<=NF;i++)if($i~/^[0-9]+$/)print $i}'

输出:

2951
2952
2954
2955

这就是拿到了主进程及其所有子进程pid了.

使用_kill_拿到的所有pid, 就可以一次性kill了

kill -9 `pstree -p 3254 | awk -F"[()]" '{for(i=0;i<=NF;i++)if($i~/^[0-9]+$/)print $i}'`

或:

pstree -p 3281 | awk -F"[()]" '{for(i=0;i<=NF;i++)if($i~/^[0-9]+$/)print $i}'|xargs kill -9

在启动一个脚本时,把pid记录到一个文件
杀进程时,根据记录的pid kill

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进