Python踩坑之旅其一杀不死的Shell子进程
发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,1.1 踩坑案例踩坑的程序是个常驻的Agent类管理进程, 包括但不限于如下类型的任务在执行:a. 多线程的网络通信包处理和控制Master节点交互有固定Listen端口b. 定期作业任务, 通过su
千家信息网最后更新 2025年12月01日Python踩坑之旅其一杀不死的Shell子进程
1.1 踩坑案例
踩坑的程序是个常驻的Agent类管理进程, 包括但不限于如下类型的任务在执行:
- a. 多线程的网络通信包处理
- 和控制Master节点交互
- 有固定Listen端口
- b. 定期作业任务, 通过subprocess.Pipe执行shell命令
- c. etc
发现坑的过程很有意思:
- a.重启Agent发现Port被占用了
- => 立刻想到可能进程没被杀死, 是不是停止脚本出问题
- => 排除发现不是, Agent进程确实死亡了
- => 通过
netstat -tanop|grep port_number发现端口确实有人占用 - => 调试环境, 直接杀掉占用进程了之, 错失首次发现问题的机会
- b.问题在一段时间后重现, 重启后Port还是被占用
- 定位问题出现在一个叫做xxxxxx.sh的脚本, 该脚本占用了Agent使用的端口
- => 奇了怪了, 一个xxx.sh脚本使用这个奇葩Port干啥(大于60000的Port, 有兴趣的砖友可以想下为什么Agent默认使用6W+的端口)
- => review该脚本并没有进行端口监听的代码
- 一拍脑袋, c.进程共享了父进程资源了
- => 溯源该脚本,发现确实是Agent启动的任务中的脚本之一
- => 问题基本定位, 该脚本属于Agent调用的脚本
- => 该Agent继承了Agent原来的资源FD, 也就是这个port
- => 虽然该脚本由于超时被动触发了terminate机制, 但terminate并没有干掉这个子进程
- => 该脚本进程的父进程(ppid) 被重置为了1
- d.问题**出在脚本进程超时kill逻辑**
1.2 填坑解法
通过代码review, 找到shell具体执行的库代码如下:
self._subpro = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=_signal_handle)# 重点是shell=True !把上述代码改为:
self._subpro = subprocess.Popen( cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, preexec_fn=_signal_handle)# 重点是去掉了shell=True1.3 坑位分析
Agent会在一个新创建的threading线程中执行这段代码, 如果线程执行时间超时(xx seconds), 会调用 self._subpro.terminate()终止该脚本.
表面正常:
- 启用新线程执行该脚本
- 如果出现问题,执行超时防止hang住其他任务执行调用terminate杀死进程
深层问题:
- Python 2.7.x中subprocess.Pipe 如果shell=True, 会默认把相关的pid设置为shell(sh/bash/etc)本身(执行命令的shell父进程), 并非执行cmd任务的那个进程
- 子进程由于会复制父进程的opened FD表, 导致即使被杀死, 依然保留了拥有这个Listened Port FD
这样虽然杀死了shell进程(未必死亡, 可能进入defunct状态), 但实际的执行进程确活着. 于是1.1中的坑就被结实的踩上了.
1.4 坑后扩展
1.4.1 扩展知识
本节扩展知识包括二个部分:
- Linux系统中, 子进程一般会继承父进程的哪些信息
- Agent这种常驻进程选择>60000端口的意义
扩展知识留到下篇末尾讲述, 感兴趣的可以自行搜索
1.4.1 技术关键字
- Linux系统进程
- Linux随机端口选择
- 程序多线程执行
- Shell执行
1.5 填坑总结
- 子进程会继承父进程的资源信息
如果只kill某进程的父进程, 集成了父进程资源的子进程会继续占用父进程的资源不释放, 包括但不限于
- listened port
- opened fd
- etc
- Python Popen使用上, shell的bool状态决定了进程kill的逻辑, 需要根据场景选择使用方式
Life is short. We use Python
工号: 程序员的梦呓指南
进程
脚本
问题
端口
代码
任务
线程
资源
知识
程序
选择
信息
兴趣
命令
时间
状态
系统
逻辑
重点
a.
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
珠海安卓软件开发报价
网络安全系统集成可以学到什么
太库科技互联网创新
服务器内存条频率8500
服务器 流量矿石
网络安全atp设备
存储管理服务器不能为空
集群使用同一个数据库连接池
软件开发中sa
深圳基石测评网络技术
服务器post
软件开发 公司有哪些
乐视 媒体服务器
数据库概念结构有哪些特点
虚拟机搭建服务器只能自己访问吗
脏小豆骗赞服务器视频
滨州软件开发入门学习哪家好
tomo服务器
数据库出生日期怎么加一年
软件开发w亿玛酷1流量订制
临床分析数据库
雅安市公安局网络安全支队
国内心血管方面的数据库
腾讯云服务器添加管理员
中级数据库
网络安全项目实施流程
gitlab服务器迁移
2022网络技术专业
倩女幽魂长安月下服务器怎么样
千秋霸业服务器我的世界