以下均为Linux环境测试。

起因:

开发的一个程序,经常会由于内存不足而被kill掉,使用的是os.system函数执行的,返回值总是35072,当时没多想。后来由于一些原因,要模拟OOM 被kill的状态,于是调用 sys.exit(35072) 突然发现,返回值不对。。。 于是有了下面的。

python中执行系统命令的方式一般来说有两种,os和subprocess(推荐)。

简单用法如下:

import os
os.system("ls")
# or
import subprocess
subprocess.call(["ls"])

本文重点在于此两种方式的返回值差异问题。

一、os.system

此函数返回值即为 os.wait 函数返回值中的 exit status,查看官方文档对 os.wait 的解释:

Wait for completion of a child process, and return a tuple containing its pid and exit status indication: a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced

os.wait 返回一个元组,包含进程id和进程退出状态码。

敲重点:

进程退出码由两部分组成,分别是进程被kill的信号值和进程的退出码。

这两个数字合并为一个16位的数字,前8位是退出码,后8位是kill信号。

10进制计算方式:

进程退出码 = 进程退出码 * 2 ** 8 + kill信号值

测试:

python中可以调用sys.exit或者os._exit来模拟各种退出码

import os

cmd = "python -c 'import sys;sys.exit(1)'"
r = os.system(cmd)
print(r) # r = 256

由于没有被kill,故kill信号值为0,所以 r = 1 * 2 ** 8 + 0 = 256

当进程被kill时,则没有退出码,故 r = kill信号值

tips:

使用 os.WEXITSTATUS 可将 os.system 返回值还原为退出码

二、subprocess.call

此函数返回的是subprocess.Popen对象的returncode属性,这个没找到文档,直接看源码吧。

def _handle_exitstatus(
self,
sts,
_WIFSIGNALED=os.WIFSIGNALED,
_WTERMSIG=os.WTERMSIG,
_WIFEXITED=os.WIFEXITED,
_WEXITSTATUS=os.WEXITSTATUS,
_WIFSTOPPED=os.WIFSTOPPED,
_WSTOPSIG=os.WSTOPSIG,
):
"""All callers to this function MUST hold self._waitpid_lock."""
# This method is called (indirectly) by __del__, so it cannot
# refer to anything outside of its local scope.
if _WIFSIGNALED(sts):
self.returncode = -_WTERMSIG(sts)
elif _WIFEXITED(sts):
self.returncode = _WEXITSTATUS(sts)
elif _WIFSTOPPED(sts):
self.returncode = -_WSTOPSIG(sts)
else:
# Should never happen
raise SubprocessError("Unknown child exit status!")

在源码中可发现,它对不同类型的退出码(或者叫退出码不太合适。。)做了判断,如果是被kill或被停止,则返回一个负值,如果是正常退出码,则原样返回。

测试:

import subprocess

r = subprocess.call(["python", "-c", "import sys;sys.exit(1)"])
print(r) # r=1

在没有被kill时,r = 退出码 = 1

当被kill时,懒得写代码了,返回值是 -9、-15等

参见:Linux 信号signal处理机制

ps:

Linux errno 的详细说明可参见:

Linux errno详解

补充一个:

errno: 137 OOM killer

参考文献:

C语言 unsigned与signed区别

https://docs.python.org/3.7/library/subprocess.html#subprocess.Popen.wait

https://docs.python.org/3.7/library/os.html#os.system

https://shapeshed.com/unix-exit-codes/

Linux errno 与 Python的更多相关文章

  1. windows和linux中搭建python集成开发环境IDE——如何设置多个python环境

    本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...

  2. 【转】windows和linux中搭建python集成开发环境IDE

    本系列分为两篇: 1.[转]windows和linux中搭建python集成开发环境IDE 2.[转]linux和windows下安装python集成开发环境及其python包 3.windows和l ...

  3. linux下安装python

    在Linux下安装Python的操作相当简单,按如下步骤操作即可: 命令: wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgzt ...

  4. Linux 下安装python软件包(pip、nose、virtualenv、distribute )

    新手刚开始学习Python,目前学习<笨方法学python>ing- 在学习习题46时需要安装几个软件包:pip.nose.virtualenv.distribute !在此记录Linux ...

  5. Linux环境下Python的安装过程

    Linux环境下Python的安装过程 前言 一般情况下,Linux都会预装 Python了,但是这个预装的Python版本一般都非常低,很多 Python的新特性都没有,必须重新安装新一点的版本,从 ...

  6. linux下安装python linux下一些常用的命令

    注意 ubuntukylin-14.04.2-desktop-amd64 自带python2.7.6 这个说的比较详细 http://wenku.baidu.com/link?url=gaeFcQrc ...

  7. linux环境下 python环境import找不到自定义的模块

    linux环境下 python环境import找不到自定义的模块 问题现象: Linux环境中自定义的模块swport,import swport 出错.swport模块在/root/sw/目录下. ...

  8. linux配置Anaconda python集成环境

    1.下载anaconda与安装 利用anaconda来配置python环境 如果你上面两步已经没有问题了,那么这一步可以省略. 如果你想简单一些,利用anaconda来配置python环境,那么直接从 ...

  9. 环境部署(九):linux下安装python+chrome+Xvfb

    在基于selenium进行的UI自动化测试中,开发调试环境一般都是windows操作系统.完成后需要部署到专门的测试环境. 如要要部署到linux环境的服务器(阿里云.腾讯云)执行,那么测试脚本也需要 ...

随机推荐

  1. Spring Boot进阶系列四

    这边文章主要实战如何使用Mybatis以及整合Redis缓存,数据第一次读取从数据库,后续的访问则从缓存中读取数据. 1.0 Mybatis MyBatis 是支持定制化 SQL.存储过程以及高级映射 ...

  2. Log4j之HelloWorld

    在编写项目的时候,我们一般都会用到日志记录,方便出错查找原因.首先我们需要了解什么是Log4j 1.使用maven建立工程,在pom.xml中加入如下: <dependency> < ...

  3. 记一次node节点异常排查

    一.背景 公司进行kubernetes服务重启演练,集群重启后所有服务正常,仅node2节点处于notready状态 二.排查过程 查看对应节点的详细信息,发现kubelet一直处于starting状 ...

  4. Excel VBA业余爱好者心得及总结

    我不是IT专业人士,而是一位医务工作者,当初学习Excel VBA时,是因为读研究生时的课题需要:实验仪器每天产生4个Word文件,每个文件有9个表格,总计近百个数据.为了对这些数据进行统计分析,则需 ...

  5. Ext.net自动保存读取GrdPanel列显示状态

    //layout保存 function SaveLayOut() { let colVisibleArray = []; for (var i = 0; i < mcp_gridlist.col ...

  6. 快速获取更丰富的Sitecore体验数据库

    无论您是否立即使用Sitecore的营销功能,我们强烈建议您执行这三项任务,以使您的数据收集更加丰富,并为您以后的决策留下良好的位置. Sitecore的体验数据库,即xDB,是Sitecore营销平 ...

  7. [终极巨坑]golang+vue开发日记【一】,环境搭建篇

    写在前面 这个golang+vue大部分的内容是基于bydmm(橙卡)大佬的视频学来的,我在这里只是做一下个人开发的笔记,就是图一个乐,毕竟我只是个应届毕业生,如果真的要学请:bydmm的b站空间. ...

  8. FPGA 开发板入手途径有哪些呢?

    买到一块 FPGA 开发板,你如何入手呢? 根据博主的经验,你可以通过如下途径来学习: 1.如果你是淘宝上买的,那么可以在淘宝上搜索你的开发板(一般 FPGA 开发板生厂商在淘宝上卖都会附带教程,如米 ...

  9. Flutter 宽高比(比率)控件 AspectRatio

    const AspectRatio({ Key key, @required this.aspectRatio, Widget child,}) void main() {  runApp(    n ...

  10. tornado之websoket

    继承WebSoketHandler def open(self): # 当一个WebSoket连接建立之后被调用 def on_message(self, message): # 当客户端发送一个消息 ...