以下均为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. vb.net 对字符串中的括号匹配进行判断,容许嵌套

    '   括号检查 '     括号共有四种:  1(英文圆括号),2(中文圆括号),3[方括号],4{花括号} '      要左右匹配(可以嵌套) Private Shared Function i ...

  2. Kdtree原理以及 vs Octree

    1. Kdtree原理 Kdtree是一种划分k维数据空间的数据结构,本质也是一颗二叉树,只不过每个节点的数据都是k维,当k=1时,就是图1所示的普通二叉树. 图1 1)Kdtree的建立 建立Kdt ...

  3. [HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的“HT”

    [HeadFrist-HTMLCSS学习笔记]第二章深入了解超文本:认识HTML中的"HT" 敲黑板!!! 创建HTML超链接 <a>链接文本(此处会有下划线,可以单击 ...

  4. 重启nova-scheduler服务,报错Login was refused using authentication mechanism AMQPLAIN

    问题描述 运行 systemctl restart openstack-nova-scheduler.service 失败,查看日志报错如下: 2019-12-22 14:52:27.426 1513 ...

  5. Laravel自动备份到阿里云OSS

    背景 之前做备份时,主要是拿一台备份机对生产机做数据库做主备,用rsync同步上传的图片,文件.随着项目的增多,许多小项目都这样做感觉太过繁琐,每次都要在2台机器之间配置,同时单独拿一台机器做备份成本 ...

  6. linux 系统时间 EST CST

    早上本来要做一些实验的,基于时间的.date 查看时间,发现时间不对.用 pool.ntp.org 去同步发现时间还是一样的,并且没有报错.如是开启另外一台时间对的linux服务器进行对比.发现一个是 ...

  7. [经验分享]ThinkPad笔记本无法进入PE环境

    首先参考:https://jingyan.baidu.com/article/72ee561a564358e16138df14.html 可以设置Secure Boot然后重启电脑,按F1重新进入BI ...

  8. odoo13 searchpanel tree

    <record id="view_department_filter" model="ir.ui.view"> <field name=&qu ...

  9. Docker学习-从无知到有知的学习过程

    Docker学习 最近被别人提到的docker吸引到了注意力,所以打算先快速的了解一下docker到底是个上面东西. 之所以我写下这个文档呢,是为了记录对docker一无所知我是如何进行学习一门新技术 ...

  10. 第七节:Asp.Net Core内置日志和整合NLog(未完)

    一. Asp.Net Core内置日志 1. 默认支持三种输出方式:控制台.调试(底部输出窗口).EventSource,当然也可以在Program类中通过logging.ClearProviders ...