一、常见subprocess方法

1、subprocess.getstatusoutput(cmd)

官方解释:

Return (exitcode, output) of executing cmd in a shell.

Execute the string 'cmd' in a shell with 'check_output' and
return a 2-tuple (status, output). The locale encoding is used
to decode the output and process newlines.

cmd可以直接执行shell命令,而不需要cmd命令以列表输入----subprocess.getstatusoutput("cat /proc/meminfo")

返回值包含cmd的执行状态和执行结果,可以直接赋值给某个变量

实例:

>>> ret = subprocess.getoutput('ls -l')
>>> print(ret)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l')
>>> print(retcode)
0
>>> print(output)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
>>> retcode, output = subprocess.getstatusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: 无法访问/test: 没有那个文件或目录

2、subprocess.getoutput(cmd)

官方解释:

Return output (stdout or stderr) of executing cmd in a shell.

Like getstatusoutput(), except the exit status is ignored and the return
value is a string containing the command's output cmd可以直接执行shell命令,而不需要cmd命令以列表输入---subprocess.getoutput("cat /proc/meminfo")
返回值包含cmd的执行结果,可以直接赋值给某个变量
功能和getstatusoutput类似

3、subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs))

Run command with arguments and return a CompletedProcess instance.   执行传入命令参数后,返回CompletedProcess实例
The returned instance will have attributes args, returncode, stdout and
stderr. By default, stdout and stderr are not captured, and those attributes
will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them. check等于True的时候,当执行状态不是0时,会抛出CalledProcessError异常提示 传入命令参数时,需要以多个命令拆分按照列表形式传入:subprocess.run(['df', '-h'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True) 如果传入参数同时传入shell=True,则传入一个字符串args,shell命令而不是待执行的shell命令序列 实例:
>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

 

4、subprocess.call()

官方解释:

Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute

 传入shell命令参数格式subprocess.check_call(["ls""-l"])

如果传入参数同时传入shell=True,则可以传入一个字符串shell命令而不是待执行的shell命令列表--subprocess.check_call("exit 1", shell=True)
返回参数仅返回执行状态码,可通过把结果复制给某个变量查看,如果直接在linux下python编译器执行该命令会直接显示命令执行的结果

实例:
>>> subprocess.call(['ls',  '-l'])
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.call('ls -l', shell=True)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.call(['ls', '-l'], stdout=subprocess.DEVNULL)
0
>>> subprocess.call(['ls', '-l', '/test'])
ls: 无法访问/test: 没有那个文件或目录
2

5、subprocess.check_call()

官方解释:

Run command with arguments.  Wait for command to complete.  If
the exit code was zero then return, otherwise raise
CalledProcessError. The CalledProcessError object will have the
return code in the returncode attribute.

check_call基本和call功能一样,只是增加了返回状态码校验,如果执行状态码是0,则返回0,否则抛出异常

实例:

>>> subprocess.check_call(['ls',  '-l'])
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.check_call('ls -l', shell=True)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面
0
>>> subprocess.check_call('ls -l /test', shell=True)
ls: 无法访问/test: 没有那个文件或目录
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 557, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2

6、subprocess.check_output()

官方解释:

Run command with arguments and return its output.

If the exit code was non-zero it raises a CalledProcessError.  The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
执行命令,如果状态码是0,则返回执行结果,否则抛出异常--
subprocess.check_output(["ls""-l"])
如果传入参数同时传入shell=True,则可以传入一个字符串shell命令而不是待执行的shell命令列表--
subprocess.check_call("exit 1", shell=True)
返回值包含cmd的执行结果,可以直接赋值给某个变量

实例:
>>> ret = subprocess.check_output(['ls',  '-l'])
>>> print(ret)
b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe5\x9b\xbe\xe7\x89\x87\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe6\x96\x87\xe6\xa1\xa3\ndrwxr-xr-x 2 wader wader 4096 4\xe6\x9c\x88 13 2016 \xe4\xb8\x8b\xe8\xbd\xbd\ndrwxr-xr-x 2 wader wader 4096 12\xe6\x9c\x88 7 2015 \xe9\x9f\xb3\xe4\xb9\x90\ndrwxr-xr-x 7 wader wader 4096 5\xe6\x9c\x88 26 2016 \xe6\xa1\x8c\xe9\x9d\xa2\n'
>>> ret = subprocess.check_output(['ls', '-l'], universal_newlines=True)
>>> print(ret)
总用量 160
drwxr-xr-x 2 wader wader 4096 12月 7 2015 公共的
drwxr-xr-x 2 wader wader 4096 12月 7 2015 模板
drwxr-xr-x 2 wader wader 4096 12月 7 2015 视频
drwxr-xr-x 2 wader wader 4096 12月 7 2015 图片
drwxr-xr-x 2 wader wader 4096 12月 7 2015 文档
drwxr-xr-x 2 wader wader 4096 4月 13 2016 下载
drwxr-xr-x 2 wader wader 4096 12月 7 2015 音乐
drwxr-xr-x 7 wader wader 4096 5月 26 2016 桌面

二、subprocess.Popen()类--用于执行复杂的系统命令

该类用于在一个新的进程中执行一个子程序。前面我们提到过,上面介绍的这些函数都是基于subprocess.Popen类实现的,通过使用这些被封装后的高级函数可以很方面的完成一些常见的需求。由于subprocess模块底层的进程创建和管理是由Popen类来处理的,因此,当我们无法通过上面哪些高级函数来实现一些不太常见的功能时就可以通过subprocess.Popen类提供的灵活的api来完成。

1、subprocess.Popen的构造函数

def __init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None)

构造函数详细参数说明和其他实现过程可以参考对应subprocess库文件

参数说明:

  • args: 要执行的shell命令,可以是字符串,也可以是命令各个参数组成的序列。当该参数的值是一个字符串时,该命令的解释过程是与平台相关的,因此通常建议将args参数作为一个序列传递。
  • bufsize: 指定缓存策略,0表示不缓冲,1表示行缓冲,其他大于1的数字表示缓冲区大小,负数 表示使用系统默认缓冲策略。
  • stdin, stdout, stderr: 分别表示程序标准输入、输出、错误句柄。
  • preexec_fn: 用于指定一个将在子进程运行之前被调用的可执行对象,只在Unix平台下有效。
  • close_fds: 如果该参数的值为True,则除了0,1和2之外的所有文件描述符都将会在子进程执行之前被关闭。
  • shell: 该参数用于标识是否使用shell作为要执行的程序,如果shell值为True,则建议将args参数作为一个字符串传递而不要作为一个序列传递。
  • cwd: 如果该参数值不是None,则该函数将会在执行这个子进程之前改变当前工作目录。
  • env: 用于指定子进程的环境变量,如果env=None,那么子进程的环境变量将从父进程中继承。如果env!=None,它的值必须是一个映射对象。
  • universal_newlines: 如果该参数值为True,则该文件对象的stdin,stdout和stderr将会作为文本流被打开,否则他们将会被作为二进制流被打开。
  • startupinfo和creationflags: 这两个参数只在Windows下有效,它们将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如主窗口的外观,进程优先级等。

2. subprocess.Popen类的实例可调用的方法

方法 描述
Popen.poll() 用于检查子进程(命令)是否已经执行结束,没结束返回None,结束后返回状态码。
Popen.wait(timeout=None) 等待子进程结束,并返回状态码;如果在timeout指定的秒数之后进程还没有结束,将会抛出一个TimeoutExpired异常。
Popen.communicate(input=None, timeout=None) 该方法可用来与进程进行交互,比如发送数据到stdin,从stdout和stderr读取数据,直到到达文件末尾。
Popen.send_signal(signal) 发送指定的信号给这个子进程。
Popen.terminate() 停止该子进程。
Popen.kill() 杀死该子进程。

关于communicate()方法的说明:

  • 该方法中的可选参数 input 应该是将被发送给子进程的数据,或者如没有数据发送给子进程,该参数应该是None。input参数的数据类型必须是字节串,如果universal_newlines参数值为True,则input参数的数据类型必须是字符串。
  • 该方法返回一个元组(stdout_data, stderr_data),这些数据将会是字节穿或字符串(如果universal_newlines的值为True)。
  • 如果在timeout指定的秒数后该进程还没有结束,将会抛出一个TimeoutExpired异常。捕获这个异常,然后重新尝试通信不会丢失任何输出的数据。但是超时之后子进程并没有被杀死,为了合理的清除相应的内容,一个好的应用应该手动杀死这个子进程来结束通信。
  • 需要注意的是,这里读取的数据是缓冲在内存中的,所以,如果数据大小非常大或者是无限的,就不应该使用这个方法

3. subprocess.Popen使用实例

实例1、

>>> import subprocess
>>>
>>> p = subprocess.Popen('df -Th', stdout=subprocess.PIPE, shell=True)
>>> print(p.stdout.read())
Filesystem Type Size Used Avail Use% Mounted on
/dev/vda1 ext4 40G 12G 26G 31% /
devtmpfs devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs tmpfs 3.9G 386M 3.5G 10% /run
tmpfs tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
tmpfs tmpfs 783M 0 783M 0% /run/user/0
tmpfs tmpfs 783M 0 783M 0% /run/user/1000

实例2

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> obj.stdin.write('print(1) \n')
>>> obj.stdin.write('print(2) \n')
>>> obj.stdin.write('print(3) \n')
>>> out,err = obj.communicate()
>>> print(out)
1
2
3 >>> print(err)

实例3

>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out,err = obj.communicate(input='print(1) \n')
>>> print(out)
1 >>> print(err)

实例4

实现类似df -Th | grep data命令的功能,实际上就是实现shell中管道的共功能

>>>
>>> p1 = subprocess.Popen(['df', '-Th'], stdout=subprocess.PIPE)
>>> p2 = subprocess.Popen(['grep', 'data'], stdin=p1.stdout, stdout=subprocess.PIPE)
>>> out,err = p2.communicate()
>>> print(out)
/dev/vdb1 ext4 493G 4.8G 463G 2% /data
/dev/vdd1 ext4 1008G 420G 537G 44% /data1
/dev/vde1 ext4 985G 503G 432G 54% /data2 >>> print(err)
None

三、总结

那么我们到底该用哪个模块、哪个函数来执行命令与系统及系统进行交互呢?下面我们来做个总结:

1、如果你的应用使用的Python 2.4以上,但是是Python 3.5以下的版本,Python官方给出的建议是使用subprocess.call()函数。Python 2.5中新增了一个subprocess.check_call()函数,Python 2.7中新增了一个subprocess.check_output()函数,这两个函数也可以按照需求进行使用

2、如果你的应用使用的是Python 3.5及以上的版本(目前应该还很少),Python官方给出的建议是尽量使用subprocess.run()函数

3、当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些高级函数无法满足需求时,我们可以使用subprocess.Popen类来实现我们需要的复杂功能

不过经过个人试验认为getoutput、getstatusoutput方法使用比较便捷,subprocess适合个性化的执行

参考链接:https://www.cnblogs.com/yyds/p/7288916.html

python3之subprocess常见方法使用的更多相关文章

  1. python3的subprocess的各个方法的区别(-)

    subprocess(python3.7) subprocess 主要是为了替换一下的模块函数,允许你执行一些命令,并获取返回的状态码和 输入,输出和错误信息. os.systemos.spawn* ...

  2. C#图片处理常见方法性能比较

    C#图片处理常见方法性能比较 来自:http://www.cnblogs.com/sndnnlfhvk/archive/2012/02/27/2370643.html   在.NET编程中,由于GDI ...

  3. window对象中的常见方法

    <body><!-- window对象中的常见方法--><script type="text/javascript"> var timeid; ...

  4. python socket 常见方法及 简单服务/客户端

    socket 常见方法: 补充说明:what is file descriptor? 文件描述符是什么? 参考(http://stackoverflow.com/questions/8191905/w ...

  5. VBS操作Excel常见方法

    VBS操作Excel常见方法 作者: 字体:[增加 减小] 类型:转载 时间:2009-11-13我要评论 VBS控制Excel常见方法,需要的朋友可以参考下. dim oExcel,oWb,oShe ...

  6. UIPickerView常见属性、常见方法(包括代理方法和数据源方法)的一些说明

    一.UIPickerView 1.UIPickerView的常见属性 // 数据源(用来告诉UIPickerView有多少列多少行) @property(nonatomic,assign) id< ...

  7. jQuery ajax调用后台aspx后台文件的两种常见方法(不是ashx)

    在asp.net webForm开发中,用Jquery ajax调用aspx页面的方法常用的有两种:下面我来简单介绍一下. [WebMethod] public static string SayHe ...

  8. AJAX跨域的常见方法

    由于在工作中需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问.比如说你的网站域名是aaa.com,想要通过AJAX请求 ...

  9. Java中字符串的一些常见方法

    1.Java中字符串的一些常见方法 /** * */ package com.you.model; /** * @author Administrator * @date 2014-02-24 */ ...

随机推荐

  1. Bash判断文件夹(目录)是否存在

    #!/bin/bash if [ -d DirName ]; then echo 'Dir exist' else echo 'Dir not exist' fi

  2. 解决 下载 CM-12.0 源代码出现 Fatal: duplicate project .....问题

    在使用 repo init -u git://github.com/CyanogenMod/android.git -b cm-12.0 初始化代码库的时候出现如下错误: fatal: manifes ...

  3. poj1847 Tram 最短路Dijkstra

    题目链接:http://poj.org/problem?id=1847 Dijkstra算法的模版应用 题意:给你N个点和起点终点,点与点有铁路,接下来的N行分别为点i的情况 第一个数字表示与该点连通 ...

  4. 百度地图api 区级以下行政区划

    我们在使用百度地图api想要展示苏州市吴中区各乡镇的行政区范围: 百度api有提供了“添加行政区划”的示例:http://lbsyun.baidu.com/jsdemo.htm#c1_10 但该功能目 ...

  5. cookielib和urllib2模块结合模拟网站登录

    1.cookielib模块 cookielib模块的主要作用就是提供可存储cookie的对象,以便于与urllib2模块配合使用来访问internet资源,例如可以利用本模块的cookiejar类的对 ...

  6. 迅为iTOP-4418/6818开发板-驱动-实现GPIO扩展

    实现 GPIO 扩展,先弄清楚“复用”的概念,将调用这些 GPIO 的驱动去掉配置,重新编译,加到自己的驱动中,就可以实现扩展的 GPIO 的输入和输出.另外必须要先看文档“迅为iTOP-4418开发 ...

  7. Terraria(泰拉瑞亚)存档覆盖(Linux)

    这是一篇关于游戏的不正经博客 ~ 游戏介绍: <泰拉瑞亚>是由Re-Logic公司开发的一款高自由度的沙盒游戏,于2011年5月16日在PC上发行. 玩家可以在游戏中做很多事情:制造武器战 ...

  8. HDU 1880 魔咒词典 (Hash)

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. JDK8新特性01 Lambda表达式01_设计的由来

    1.java bean public class Employee { private int id; private String name; private int age; private do ...

  10. Spring 学习教程(三):Spring MVC

    1. 用户访问 /index2. 根据web.xml中的配置 所有的访问都会经过DispatcherServlet3. 根据 根据配置文件springmvc-servlet.xml ,访问路径/ind ...