python 中 os 模块用得比较多,但 os.system 实际上是怎么调用 shell 命令的呢?简单来探寻一下。

1、系统环境

macos 10.15.6 x86_64

python 3.8.5

为什么要强调系统环境,因为 python 在不同系统版本上实现可能会有差异,待会讲解就能发现了。

2、os 模块

通过 help(os) 可以找到源文件查看,

下面截取相关代码来看(直接用注释解释了):

# 返回一个包含内建模块名字的元组,包含所有已经编译到Python解释器的模块名字

_names = sys.builtin_module_names

# __all__ 只影响到了 from import * 这种导入方式

def _get_exports_list(module):

try:

return list(module.__all__)

except AttributeError:

return [n for n in dir(module) if n[0] != '_']

# 判断当前操作系统类型

# posix代表类Unix系统,nt表示Windows系统

# 我们的 macOS 就是类Unix系统,只截取这部分代码

if 'posix' in _names:

name = 'posix' # 表示操作系统类型

linesep = '\n' # 定义了当前平台使用的行终止符

# os模块其实就是对posix或nt模块的二次封装,这样的好处就是实现了对不同平台的兼容

from posix import *

try:

from posix import _exit

__all__.append('_exit')

except ImportError:

pass

import posixpath as path # 我们常用的os.path实际上是ntpath或者posixpath模块

try:

from posix import _have_functions

except ImportError:

pass

import posix

__all__.extend(_get_exports_list(posix))

del posix

现在我们知道了在 macos 平台上,os 模块实际上是对 posix 模块的封装。

2.1、subprocess 模块

顺道再看看 subprocess 调用的实现:

if shell: #制作 shell 的参数

args = ["/bin/sh", "-c"] + args

if executable:

args[0] = executable

if executable is None:

executable = args[0]

# ··· ···

self.pid = os.fork() #创建子进程

# ··· ···

os.execvp(executable, args) #执行 shell 命令

3、posix 模块

posix 即 Portable Operating System Interface(可移植操作系统接口),是类 Unix 系统的兼容标准。

同样通过 help(posix) 看下是否有源文件,

可以看到 posix 是 built-in module,代表是直接编译好放在 python 这个可执行文件里的。

可以在 module 的 config.c 中找到相关的转接代码。

extern void initposix(void);

struct _inittab _PyImport_Inittab[] = {

{"posix", initposix},

// ...

3.1、对 built-in 模块的继续查找

实际上对于 built-in 模块还能继续查找,首先要弄清楚当前 python 的虚拟机是用什么实现的:

可以看到 macos 系统 python 虚拟机是 CPython 实现的。

CPython 是开源的,那么我们可以从 cpython 中找到相关的源码:

static PyMethodDef posix_methods[] = {

... ...

#ifdef HAVE_SYSTEM {"system", posix_system, METH_VARARGS, posix_system__doc__},

#endif... ...

};

#ifdef HAVE_SYSTEMPyDoc_STRVAR(posix_system__doc__,

"system(command) -> exit_status\n\n\Execute the command (a string) in a subshell.");

// 在Python中操作的任何元素都是一個由C語言實現的PyObject對象static PyObject *

posix_system(PyObject *self, PyObject *args)

{

char *command;

long sts;

if (!PyArg_ParseTuple(args, "s:system", &command))

return NULL;

Py_BEGIN_ALLOW_THREADS // 允许其他线程获取 GIL 锁来跑 sts = system(command); // system call(或其他不会操作Python Data的调用) Py_END_ALLOW_THREADS // 重新获取 GIL 锁 return PyInt_FromLong(sts);

}

#endif

可以看到 posix.system 最终会调用 C 的 system 函数。

C 的 system 函数就不需要再深入进去了,在 C/C++ 网站有很多介绍。

4、结论

macos 系统下:

os.system -> posix.system -> C 的 system 函数

python os模块system_python 中 os.system 的本质 | 编程知识2相关推荐

  1. python怎么导入os模块_python3中OS模块

    os模块 OS模块简单的来说它是一个Python的系统编程的操作模块,可以处理文件和目录这些我们日常手动需要做的操作. 可以查看OS模块的帮助文档: import os:#导入os模块 help(os ...

  2. python里的os模块_python中os模块再回顾

    先看下我的文件目录结构 F:\PYTHON项目\ATM购物车\7月28 在此目录下的文件如下: 封装.py 模块os.sys复习.py 运行当前的文件是模块os.sys复习.py 1.获取当前文件所在 ...

  3. python os.system_python中os.system()的返回值

    最近遇到os.system()执行系统命令的情况,上网搜集了一下资料,整理如下,以备不时之需,同时也希望能帮到某些人. 一.python中的 os.system(cmd)的返回值与linux命令返回值 ...

  4. python os system_python中os.system返回值为-1是什么意思?

    其实这是一个比较复杂的问题. 你是通过 os.system() 这个函数来获得的返回值,那么其内部调用的是通过 C++/C 写的和操作系统交互的 Python 底层代码.这里你没有说明你的操作系统是 ...

  5. python os模块system_Python如何使用OS模块调用cmd

    在os模块中提供了两种调用 cmd 的方法,os.popen() 和 os.system() os.system(cmd) 是在执行command命令时需要打开一个终端,并且无法保存command命令 ...

  6. python中os模块教程_python os模块功能和方法总结

    os.sep     可以取代操作系统特定的路径分割符 os.linesep  字符串给出当前平台使用的行终止符.例如,Windows使用' ',Linux使用' ' 而Mac使用''. os.nam ...

  7. python找不到os模块_Python中的OS模块:您需要知道的一切

    Python是当今业界最强大的编程语言之一.由于Python具有许多特性和强大的通用性,许多复杂的编程目标可以很容易地在Python中实现.在本文中,我们将按照以下顺序讨论Pyt Python是当今业 ...

  8. python 基本模块 random、os、sys

    一.random模块 所有关于随机相关的内容都在random模块中 import random print(random.random()) # 0-1⼩数 print(random.uniform( ...

  9. python安装os模块_python的os模块(ipython,文件,目录,权限,管理)

    什么是os模块 os模块提供了多数操作系统的功能接口函数.当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在python编程时,经常和文件.目录打交道,这时就离不了o ...

最新文章

  1. php 事件调度,mysql数据库事件调度(Event)
  2. linux修改权限掩码,Linux中控制文件权限修改的chgrp和umask命令用法
  3. 根据 xsd 生成 jaxb java 类
  4. springboot 跨域_SpringBoot跨域加SpringSecurity就失效
  5. WPF在预览视图下可以看到图片,运行时却报错提示找不到资源
  6. 面向切面编程--AOP
  7. linux msgctl函数,msgctl()函数
  8. Gradient Boosting算法理论
  9. 【JavaEE】第一章线程和多线程
  10. Oracle从10g升级到11g详细步骤
  11. tp5设置session过期时间
  12. [Excel图表实战技巧精粹].Excel.Home.扫描版 百度云
  13. 软件观念革命:交互设计精髓_2021年中国传媒大学设计学考研招生分析、参考书目、复试线、真题回忆、考研经验指南篇...
  14. VB写的随机点名器代码
  15. arcgis 实验教程 第二章 ArcCatalog 简单操作--字段排序
  16. Makefile与前缀后缀相关函数suffix、basename、addsuffix、addprefix
  17. PHP京东商城爬取网页乱码问题解决
  18. 《英语语法新思维初级教程》学习笔记(六)实义动词与(情态)助动词
  19. python自动化plc_PYTHON – 让“Monty 语言”进入自动化行业:第 4 部分
  20. MM-DD-RRRR / MM-DD-YYYY 的区别【Blog 搬家】

热门文章

  1. CentOS7 安装并使用Ovirt 4.2
  2. [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(三) -- 安装confluence 6.6.1
  3. windows下的MySql实现读写分离
  4. GridView行号大集合
  5. LA3971 组装电脑
  6. 【micropython】用python来进行BadUSB的USB-HID测试(含无线控制)
  7. 【转】notepad++设置字体和字体大小
  8. 答TOGAF企业架构的一些问题
  9. 使用tensorflow serving部署keras模型(tensorflow 2.0.0)
  10. linux shell数组定义、元素获取及其长度获取