以下均为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. 执行git log/status等命令时,重新打开了个窗口,必须按q才能退出

    终端运行: git config --global core.pager ''

  2. #ifndef #define #endif

    在一个大的软件工程里面,可能会有多个文件同时包含一个头文件,当这些文件编译链接成一个可执行文件时,就会出现大量重定义的错误.在头文件中实用#ifndef #define #endif能避免头文件的重定 ...

  3. 分布式事务解决方案(一) 2阶段提交 & 3阶段提交 & TCC

    参考文档:http://blog.jobbole.com/95632/https://yq.aliyun.com/articles/582282?spm=a2c4e.11163080.searchbl ...

  4. k8s之发布管理架构图01

    k8s发布管理所用到的组件

  5. cad.net 块裁剪边界反向修剪

    Querying for XCLIP information inside AutoCAD using .NET  这里下面观众讨论了 How do I determine if an x-clip ...

  6. linux部署go

    一.下载tar包并解压 yum -y install wget glibc.i686 #后面一个是依赖包,不安装会报错: /lib/ld-linux.so.2: bad ELF interpreter ...

  7. Java还是编程语言中的老大?凭什么长期霸占第一宝座?

    首先,Java语言之所以能够迅速在科技行业内普及,一个重要的原因是Java语言的出现恰好契合了Web时代对于编程语言的要求,可以说Java语言的大流行是互联网时代发展的必然结果,虽然Java自身有诸多 ...

  8. Excel 简单使用

    1.Excel复制上一行 注意鼠标的样子 2.删除多行 删除之后如图所示: 删除多列也是同样的操作 3.日期格式不能按照数据库的形式进行输入 数字的位数太多输入之后改变了数字,可以设置为文本格式,进行 ...

  9. Java 中常见的 final 类

    Java 中常见的 final 类 java.lang 包 public final class Boolean extends Object implements Serializable, Com ...

  10. JSR223 PostProcessor VS BeanShell PostProcessor in JMeter

    I would recommend using JSR223 PostProcessor About performance: In JMeter's official user manual, Ab ...