除了常见的os.system和os.popen方法,官方强烈推荐使用subprocess来调用系统命令。

这个库用起来其实很简单,按照惯例先贴一下官文关键点:

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.

The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle.
For more advanced use cases, the underlying Popen interface can be used directly.

推荐的使用方式是:任何场景下,只要调用run()方法即可,已经封装好了一切。

底层接口Popen也可以直接使用,不过要注意管道堵塞问题。

API说明如下:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, ...)

Run the command described by args. Wait for command to complete, then return a CompletedProcess instance. 执行命令,等待执行完成,返回CompletedProcess实例
args is required for all calls and should be a string, or a sequence of program arguments.
If passing a single string, shell must be True.
If shell is True, the specified command will be executed through the shell.
On POSIX with shell=True, the shell defaults to /bin/sh. 默认shell是/bin/sh
subprocess.PIPE
Special value that can be used as the stdin, stdout or stderr argument to Popen and indicates that a pipe to the standard stream should be opened. subprocess.STDOUT
Special value that can be used as the stderr argument to Popen and indicates that standard error should go into the same handle as standard output.
合并错误输出到标准输出
class subprocess.CompletedProcess

The return value from run(), representing a process that has finished.

args
The arguments used to launch the process. This may be a list or a string. returncode
Exit status of the child process. Typically, an exit status of 0 indicates that it ran successfully.
A negative value -N indicates that the child was terminated by signal N (POSIX only). stdout
Captured stdout from the child process. A bytes sequence, or a string if run() was called with an encoding, errors, or text=True.

看不懂英文的同学可以略过API说明,下面来说使用姿势。

这里提供两种传参方式,一种是将要执行的命令以一整个字符串传入,一种是以序列方式传入,具体来说是这样:

subprocess.run(["ls", "-l"])
subprocess.run('ls -l', shell=True)
r = subprocess.run('ls -l', shell=True, stdout=PIPE, stderr=subprocess.STDOUT)
print(r)
print(type(r))
print(r.stdout.decode()) # 获取结果
print(r.returncode)

仅此而已,就这么简单。


关于Popen,简单说几句。

This will deadlock when using stdout=PIPE or stderr=PIPE and the child process generates enough output to a pipe,
such that it blocks waiting for the OS pipe buffer to accept more data. Use Popen.communicate() when using pipes to avoid that.

官文说Popen中使用PIPE可能会造成堵塞,建议使用Popen.communicate()来避免这个问题。

这一点,run()方法已经封装解决了,直接使用run()方法可以不理会这个问题。

解决这个问题还有一个思路,就是不用PIPE。使用临时文件保存输出。

from subprocess import Popen
from tempfile import TemporaryFile with TemporaryFile(mode='w+b') as f: # 使用临时文件保存输出结果,避免死锁
with Popen('ifconfig', shell=True, stdout=f, stderr=subprocess.STDOUT) as proc:
status = proc.wait()
f.seek(0) # 写文件时指针在文末所以读取文件需要移动指针
print(f.read().decode())
print(status)

另外,这个模块里面还有一个老方法可以用来执行命令。

implicitly invoke the system shell.

subprocess.getoutput(cmd)
Return output (stdout and stderr) of executing cmd in a shell.
r = subprocess.getoutput('ls -l')
print(r)
print(type(r))
# <class 'str'>

一句话,请使用subprocess.run()方法,其它可以忽略。

参考:

https://docs.python.org/3/library/subprocess.html

https://docs.python.org/3/library/tempfile.html

调用系统命令之subprocess模块的更多相关文章

  1. 23-[模块]-subprocess模块

    1.调用系统命令 我们经常需要通过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程之外的,每执行一条命令,就是发起一个新进程,通过python调用系统命令或脚本的 ...

  2. python常用模块-调用系统命令模块(subprocess)

    python常用模块-调用系统命令模块(subprocess) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. subproces基本上就是为了取代os.system和os.spaw ...

  3. Python 调用系统命令的模块 Subprocess

    Python 调用系统命令的模块 Subprocess 有些时候需要调用系统内部的一些命令,或者给某个应用命令传不定参数时可以使用该模块. 初识 Subprocess 模块 Subprocess 模块 ...

  4. 使用python的subprocess模块调用linux系统命令

    subprocess模块主要有call().check_call().check_output().Popen()函数,简要描述如下: Main API ======== call(...): Run ...

  5. Python用subprocess的Popen来调用系统命令

    当我们须要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.可是这两个命令过于简单,不能完毕一些复杂的操作,如给执行的命令提供输入或者读取命令的输出, ...

  6. Python使用subprocess的Popen要调用系统命令

    当我们须要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.可是这两个命令过于简单.不能完毕一些复杂的操作,如给执行的命令提供输入或者读取命令的输出, ...

  7. s14 第5天 时间模块 随机模块 String模块 shutil模块(文件操作) 文件压缩(zipfile和tarfile)shelve模块 XML模块 ConfigParser配置文件操作模块 hashlib散列模块 Subprocess模块(调用shell) logging模块 正则表达式模块 r字符串和转译

    时间模块 time datatime time.clock(2.7) time.process_time(3.3) 测量处理器运算时间,不包括sleep时间 time.altzone 返回与UTC时间 ...

  8. Python模块之subprocess--使用Popen来调用系统命令

    当我们需要调用系统的命令的时候,最先考虑的os 模块.用os.system()和os.popen()来进行操作.但是这两个命令过于简单,不能完成一些复杂的操作,如给运行的命令提供输入或者读取命 令的输 ...

  9. Python学习笔记——基础篇【第六周】——Subprocess模块

    执行系统命令 可以执行shell命令的相关模块和函数有: os.system os.spawn* os.popen*          --废弃 popen2.*           --废弃 com ...

随机推荐

  1. .NET持续集成与自动化部署之路第三篇——测试环境到生产环境的一键部署策略(Windows)

    Jenkins测试环境到生产环境的一键部署策略(Windows) 一.前言     前面我们已经初步实现了开发集成环境.测试环境的持续集成(自动化构建.自动化测试.自动化部署).但生产环境自动化部署迟 ...

  2. 我的devops实践经验分享一二

    前言 随着系统越来越大,开发人员.站点.服务器越来越多,微服务化推进,......等等原因,实现自动化的devops越来越有必要. 当然,真实的原因是,在团队组建之初就预见到了这些问题,所以从一开始就 ...

  3. 第三个spring冲刺第4天

    今天,我们在难度选择方面做了谈论,根据难度选择题目的难易和数量,在计时器方面应该有相应的配合,由此决定难易度,因此,我们要做好谈论,为这个难易度做好准备去编译,以免出现混乱.

  4. 四则运算APP

    1)   N (Need 需求) 用户基本需求:随机生成四则运算,能自动判定对错,答错时能提示正确答案! 在这个基础上,我的创意: 多用户模式,能记录用户的答题情况(登陆功能) 分级挑战,按照不同的水 ...

  5. DockerHub使用简介

    常用的Docker镜像文件都有,就不用自己费劲的一点点配置了,这才是Docker的真正目的.就像Ghost里边含office,直接还原,不用一台台机器安装呢,省时省力,与高效工作的理念相契合. 至于, ...

  6. Kitematic when login show Error:Tunning socket could not be established

    https://cn.bing.com/search?q=tunning+socket+could+not+be+established&qs=n&form=QBRE&sp=- ...

  7. [转载]Linux目录说明

    原作者博客: http://blog.51cto.com/yangrong/1288072 将文字部分转移到自己的目录下便于学习记录 感谢~ 2./目录 目录 描述 / 第一层次结构的根.整个文件系统 ...

  8. Docker 网络部分的简单学习以及转帖别人的blog

    1. 感谢一下 大神: http://www.cnblogs.com/sparkdev/ 最近有时间的话 就会读一下他的博客.学习了解docker相关的知识 今天简单做了下 测试 在这里面记录一下. ...

  9. 关于一个常用的CheckBox样式

    我们在使用CheckBox的时候,原始的样式有时不能满足我们的需求,这是我们就需要更改其模板,比如我们常用的一种,在播放器中“播放”.“暂停”按钮,其实这也是一种CheckBox,只不过我们只是修改了 ...

  10. spring cloud实战与思考(一) spring config全局配置方案设计

    “spring cloud”的配置中心工具“spring cloud config”提供了分布式系统配置文件集中管理解决方案.该工具功能强大,实现也很简单.网上可以搜索到很多开发教程和用例.本文并不是 ...