Python踩坑之旅其二裸用os.system的原罪
| 代码示例支持 |
|---|
| 平台: Centos 6.3 |
| Python: 2.7.14 |
| Github: https://github.com/baidu/CUP |
1.1 踩坑案例
今天的坑不仅包括裸用os.system还包括裸用相关的家族:
- os.popen
- subprocess家族
- subprocess.call
- subprocess.Popen
- subprocess.run
- commands家族 (py2.6后已不推荐使用, depreciated. Py3删除)
- commands.getstatusoutput
- subprocess家族
这些坑是新同学非常容易踩,而且 code review 过程中容易漏掉:
[1] 长期运行 Service 中裸用以函数家族
- 裸用以上 shell 执行家族可能出现script 执行 hang 住进而 hang 住逻辑执行线程,长时间积累进而占满所有执行线程而服务宕机情况
- 大内存消耗 service fork 子进程直接执行 script
- 如果该 script hang 住
- 并且原进程内存进行频繁修改(或者堆积修改, 虽然有 Copy-On-Write技术),但由于内存巨大,依然有内存风险
[2] 自动化测试中裸用以上函数家族而不加以保护
- 单个 case 如果执行 script 脚本 hang 住会导致 hang 掉整个case 集
- 不设计 case 超时机制导致case 集合运行时间不可控
1.2 填坑解法
- 支持超时 kill 策略,禁止任何情况下的 shell 执行裸用家族函数
提供一个作者的代码参考: https://github.com/baidu/CUP/blob/master/cup/shell/oper.py
from cup import shell
shellexec = shell.ShellExec()
# timeout=None will block the execution until it finishes
shellexec.run('/bin/ls', timeout=None)
# timeout>=0 will open non-blocking mode
# The process will be killed if the cmd timeouts
shellexec.run(cmd='/bin/ls', timeout=100)
见ShellExec类的run函数
- 内存消耗型服务/进程, 长期运行服务进程避免fork 进程执行 shell 命令
1.3 坑位分析
建议看下第二章节关于进程和子进程继承类信息,script使用上述家族进行执行时,采用了启动一个子进程的方式
1.4.1 技术关键字
- os.system家族
- subprocess家族
1.5 填坑总结
Shell执行是个非常常见的操作,所以很多同学特别是新同学,在使用过程中经常不注意而随意使用。 裸用一时爽,进程死亡火葬场
2. 前坑回顾
2.1 Linux中, 子进程拷贝父进程哪些信息
- 先说与父进程不同的
- pid, ppid
- memory locks
- tms_utime、tms_stime、tms_cutime、tms_ustime
- pending signals
- semaphore adjustments
- file lock
- pending alarms
参考资料来源:
- Linux Programmer's Manual (
man fork)- CentOS release 6.3 (Final)
- Linux Kernel 2.6.32
fork() creates a new process by duplicating the calling process. The new process, referred to as the child, is an exact duplicate of the calling process, referred to as the parent, except for the follow-
ing points:
* The child has its own unique process ID, and this PID does not match the ID of any existing process group (setpgid(2)).
* The child's parent process ID is the same as the parent's process ID.
* The child does not inherit its parent's memory locks (mlock(2), mlockall(2)).
* Process resource utilizations (getrusage(2)) and CPU time counters (times(2)) are reset to zero in the child.
* The child's set of pending signals is initially empty (sigpending(2)).
* The child does not inherit semaphore adjustments from its parent (semop(2)).
* The child does not inherit record locks from its parent (fcntl(2)).
* The child does not inherit timers from its parent (setitimer(2), alarm(2), timer_create(2)).
* The child does not inherit outstanding asynchronous I/O operations from its parent (aio_read(3), aio_write(3)), nor does it inherit any asynchronous I/O contexts from its parent (seeio_setup(2)).
The process attributes in the preceding list are all specified in POSIX.1-2001. The parent and child also differ with respect to the following Linux-specific process attributes:
* The child does not inherit directory change notifications (dnotify) from its parent (see the description of F_NOTIFY in fcntl(2)).
* The prctl(2) PR_SET_PDEATHSIG setting is reset so that the child does not receive a signal when its parent terminates.
* Memory mappings that have been marked with the madvise(2) MADV_DONTFORK flag are not inherited across a fork().
* The termination signal of the child is always SIGCHLD (see clone(2)).
在说继承、拷贝父进程的
- 包括
- 内部数据空间
- 堆栈
- 用户 ID、组 ID、eid 有效用户 id、有效组 id、用户 id 标志和设置组 id 标志
- 进程组 id
- 会话 id
- 终端
- 当前目录、根目录
- 文件模式屏蔽字
- 信号屏蔽设置
- 打开文件描述符
- 环境
- 共享存储段
- 存储映射
- 资源限制
此外
- 在父进程创建 (fork) 出一个子进程过程中, 为了加速, 会使用叫做 copy-on-write 的技术.
- 这项技术在存储软件领域也经常使用
- 附上一个关于它的讨论,点击查看
2.2 Agent常驻进程选择>60000端口的意义
在 Linux 系统中, 一般系统会自动替程序选择端口连接到用户指定的目的端口, 而这个端口范围是提前设定好的, 比如作者的 centos:
$ cat /proc/sys/net/ipv4/ip_local_port_range
10000 60000
- 选择 60000 以上的端口可以避免冲突
- 附上一篇讨论该ip_local_port_range的文章,欢迎查看
Python踩坑之旅其二裸用os.system的原罪的更多相关文章
- Python踩坑之旅其一杀不死的Shell子进程
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 坑后扩展 1.4.1 扩展知识 1.4.1 技术关键字 1.5 填坑总结 1.1 踩坑案例 踩坑的程序是个常驻的Agent类管理进程 ...
- Python 踩坑之旅进程篇其三pgid是个什么鬼 (子进程\子孙进程无法kill 退出的解法)
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 Github: https: ...
- [代码修订版] Python 踩坑之旅 [进程篇其四] 踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 公 ...
- Python 踩坑之旅进程篇其四一次性踩透 uid euid suid gid egid sgid的坑坑洼洼
目录 1.1 踩坑案例 1.2 填坑解法 1.3 坑位分析 1.4 技术关键字 1.5 坑后思考 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: 2.7.14 代码示例: 菜 ...
- [代码修订版] Python 踩坑之旅进程篇其五打不开的文件
目录 1.1 踩坑案例 1.2 填坑和分析 1.2.1 从程序优化入手 1.2.2 从资源软硬限入手 1.4.1 技术关键字 下期坑位预告 代码示例支持 平台: Centos 6.3 Python: ...
- Python 踩坑之旅文件系统篇其一文件夹也是个文件
目录 1.1 案例 1.2 分析 1.3 扩展 1.4 技术关键字 下期预告 代码示例支持 平台: Mac OS Python: 2.7.10 代码示例: - wx: 菜单 - Python踩坑指南代 ...
- EasyTrader踩坑之旅总结
easytrader是用python写的可以调用主要券商完成自动化炒股的一个软件 ,但我用的是同花顺,在研究过程中,发现同花顺暂时调不通.后来搜索发现thstrade的源码作者说是easytrad ...
- 我的微信小程序入门踩坑之旅
前言 更好的阅读体验请:我的微信小程序入门踩坑之旅 小程序出来也有一段日子了,刚出来时也留意了一下.不过赶上生病,加上公司里也有别的事,主要是自己犯懒,就一直没做.这星期一,赶紧趁着这股热乎劲,也不是 ...
- vue+ vue-router + webpack 踩坑之旅
说是踩坑之旅 其实是最近在思考一些问题 然后想实现方案的时候,就慢慢的查到这些方案 老司机可以忽略下面的内容了 1)起因 考虑到数据分离的问题 因为server是express搭的 自然少 ...
随机推荐
- linux 使用总结
shell 简单的实现守护进程 单纯的使用 &命令 + ctrl+D退出终端 原理: 关闭终端有两种方式,一种是点叉,这时候,你关闭的是gnome-terminal这个进程,而Bash是它的子 ...
- python爬虫知识点总结(七)PyQuery详解
官方学习文档:http://pyquery.readthedocs.io/en/latest/api.html 一.什么是PyQuery? 答:强大有灵活的网页解析库,模仿jQuery实现.如果你觉得 ...
- AtCoder Grand Contest 004 C:AND Grid
题目传送门:https://agc004.contest.atcoder.jp/tasks/agc004_c 题目翻译 给你一张网格图,指定的格子是紫色的,要求你构造出两张网格图,其中一张你可以构造一 ...
- Vijos:P1234口袋的天空
背景 小杉坐在教室里,透过口袋一样的窗户看口袋一样的天空. 有很多云飘在那里,看起来很漂亮,小杉想摘下那样美的几朵云,做成棉花糖. 描述 给你云朵的个数N,再给你M个关系,表示哪些云朵可以连在一起. ...
- POJ1511(最短路大数据处理)
Invitation Cards Time Limit: 8000MS Memory Limit: 262144K Total Submissions: 23357 Accepted: 767 ...
- JAVA,MYSQL,ORACLE的数据类型对比
MySQL Data Type Oracle Data Type Java BIGINT NUMBER(19, 0) java.lang.Long BIT RAW byte[] BLOB BLOB, ...
- POJ 3258 最小值最大化 二分搜索
题意:牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离, 现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值. ...
- JS编写简易计算器
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/html"> <head lang=" ...
- string.Format的困惑
今天在执行一个format时出现了这样一个问题,困惑了很久,就是 string.Format("{0:00}",“1”)结果是1 string.Format("{0:00 ...
- vs2013错误 1 Unable to find messages file 'cscui.dll'
最近使用VS编译的时候,提示错误 错误 1 Unable to find messages file 'cscui.dll' 搜索后,几乎只有1个结果,就是搜索cscui.dll 把正常大小的文件替 ...