音效素材网提供各类素材,打造精品素材网站!

站内导航 站长工具 投稿中心 手机访问

音效素材

Python执行外部命令subprocess的使用详解
日期:2021-09-08 14:19:48   来源:脚本之家

一、了解subprocess

  • subeprocess模块是python自带的模块,无需安装,主要用来取代一些就的模块或方法,如os.system、os.spawn*、os.popen、commands.*等。
  • 因此执行外部命令优先使用subprocess模块

1、subprocess.run()方法

subprocess.run()方法是官方推荐的方法,几乎所有的工作都可以用它来完成。
如下是函数源码:

subprocess.run(args,
 *,
stdin=None,
input=None,
stdout=None,
stderr=None,
shell=False,
ced=None,
timeout=None,
check=False,
enccoding=None,
error=None)

该函数返回一个CompletedProcess类(有属性传入参数及返回值)的实例,该函数的参数有很多,只需要记住常用的即可

1、args : 代表需要在操作系统中执行的命令,可以是字符串形式(要求shell=True),也可以是list列表类型
2、* :代表可变参数,一般是列表或者字典类型
3、stdin、stdout、stderr :指定了可执行程序的标准输入、标准输出、标准错误文件句柄
4、shell :代表着程序是否需要在shell上执行,当想使用shell的特性时,设置shell=True,这样就可以使用shell指令的管道、文件名称通配符、环境变量等,不过python也提供了很多类似shell的模块,如glob、fnmatch、os.walk()、os.path.expandvars()、os.path.expanduser()和shutil。
5、check :如果check设置为True,就检查命令的返回值,当返回值为0时,将抛出AclledProcessError的异常
6、timeout :设置超时时间,如果超时则kill掉子进程

1.使用字符串方式执行shell命令

[root@localhost python]# vim 1.py
#!/bin/env python3
import subprocess
b=subprocess.run("ls -l /ltp | head -2", shell=True) # 执行run方法,并将返回值赋值给b
# total 184980
# -rw-r--r--. 1 root root     10865 May  8 16:21 123.txt

print(b)              # 执行该run函数后返回的CompletedProcess类
# CompletedProcess(args='ls -l /ltp | head -2', returncode=0)

print(b.args)         # 打印出CompletedProcess类的agrs属性值,就是执行的shell命令
# ls -l /ltp | head -2

print(b.returncode)   # 打印命令执行的状态码
# 0

结果展示

[root@localhost python]# ./1.py
total 184980
-rw-r--r--. 1 root root     10865 May  8 16:21 123.txt

CompletedProcess(args='ls -l /ltp | head -2', returncode=0)2

ls -l /ltp | head -2

0

2.使用列表方式执行

个人感觉方法二不好用,尤其是想要使用管道符号是,很难用

#!/bin/env python3
import subprocess
b = subprocess.run(["ls", "-l", "/ltp"])
print(b)
print(b.args)
print(b.returncode)

执行结果

[root@localhost python]# ./2.py
total 10865
-rw-r--r--. 1 root root     10865 May  8 16:21 123.txt
CompletedProcess(args=['ls', '-l', '/ltp'], returncode=0)
['ls', '-l', '/ltp']
0

3.捕获脚本输出

  •  如果需要采集命令执行的结果,可以传入参数stdout=subprocess.PIPE
[root@localhost python]# cat 3.py
#!/bin/env python3
import subprocess
# 传入stdout=subprocess.PIPE参数即可
b=subprocess.run("ls -l /ltp | head -2", shell=True, stdout=subprocess.PIPE)

print(b.stdout)

结果显示

[root@localhost python]# ./1.py
b'total 184980\n-rw-r--r--. 1 root root     10865 May  8 16:21 123.txt\n'

4.检测异常

示例1:模拟renturncode值不为0

传入参数check=True,当返回值不为0时,就会抛出异常

[root@localhost python]# cat 1.py
#!/bin/env python3
import subprocess
b=subprocess.run("ls -l /123 | head -2 && exit 1", shell=True, stdout=subprocess.PIPE, check=True)
print(b.returncode)

执行结果:返回了CalledProcessError 类型报错

[root@localhost python]# ./1.py
ls: cannot access /123: No such file or directory
Traceback (most recent call last):
  File "./1.py", line 3, in <module>
    b=subprocess.run("ls -l /123 | head -2 && exit 1", shell=True, stdout=subprocess.PIPE, check=True)
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 487, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'ls -l /123 | head -2 && exit 1' returned non-zero exit status 1.
# 返回了 CalledProcessError 类型报错

示例2:模拟执行超时

返回 TimeoutExpired 异常

[root@localhost python]# vim 1.py
#!/bin/env python3
import subprocess

b=subprocess.run("while 2>1;do sleep 1;done",timeout=3, shell=True, stdout=subprocess.PIPE, check=True)

print(b.returncode)

显示结果

[root@localhost python]# ./1.py
Traceback (most recent call last):
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 474, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 939, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 1682, in _communicate
    self._check_timeout(endtime, orig_timeout)
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 982, in _check_timeout
    raise TimeoutExpired(self.args, orig_timeout)
subprocess.TimeoutExpired: Command 'while 2>1;do sleep 1;done' timed out after 3 seconds

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./1.py", line 3, in <module>
    b=subprocess.run("while 2>1;do sleep 1;done",timeout=3, shell=True, stdout=subprocess.PIPE, check=True)
  File "/usr/local/python3/lib/python3.7/subprocess.py", line 479, in run
    stderr=stderr)
subprocess.TimeoutExpired: Command 'while 2>1;do sleep 1;done' timed out after 3 seconds

2、Popen类

1.初步认识Popen类

首先来看一下Popen类的构造函数

class Popen(
    args,
    bufsize=0,
    executable=None,
    stdin=None,
    stdout=None,
    stderr=None,
    preexec_fn=None,
    close_fds=False,
    shell=False,
    cwd=None,
    env=None,
    universal_newlines=False,
    startupinfo=None,
    creationflags=0
):

参数 字符串或列表bufsize0 : 无缓冲

参数 字符串或列表
bufsize 0 : 无缓冲
1 : 行缓冲
其他正数值 :缓冲区大小
负数值 :采用默认的系统缓冲(一般是全缓冲)
executable 一般不用,args 字符串或列表 的第一项表示程序名
stdin
stdout
stderr
None : 没有任何重定向 继承父进程
PIPE : 创建管道
文件对象
文件描述符(整数)
stderr也可以设置为stdout
preexec_fn 钩子函数,在fork和exec之间执行
close_fds unix 下执行新进程前是否关闭0/1/2之外的文件
windows 下不继承还是继承父进程的文件描述
shell 若为True的话 :
在unix 下相当于在args前面添加了 “/bin/bash” “-c"
在windows下,相当于添加了"cmd.exe /c”
cwd 设置工作目录
env 设置环境变量
unviersal_newlines 各种换行符统一处理成"\n"
startupinfo windows下传递给CreateProcess的结构体
creationflags windows下,传递CREATE_NEW_CONSOLE创建自己的控制台窗口

2.Popen的使用方法

1、subprocess.Popen([“cat”, “abc.txt”])
2、subprocess.Popen(“cat abc.txt”, shell=True)

上面的第二种其实就相当于:subprocess.Popen(["/bin/bash", “-c”, “cat abc.txt”])

示例:

[root@localhost python]# cat 3.py
#!/bin/env python3
import subprocess
obj = subprocess.Popen("ls -l /ltp",
                       shell=True,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       universal_newlines=True)
error_info = obj.stderr.read()
out_info = obj.stdout.read()
result = out_info + error_info
print(result)

[root@localhost python]# ./3.py
total 184980
-rw-r--r--. 1 root root     10865 May  8 16:21 123.txt
-rw-r--r--. 1 root root       802 Apr 21 09:42 ab.sh
drwxr-xr-x. 3 root root       101 Apr  1 18:34 auth
-rw-r--r--. 1 root root   5242880 Mar 18 13:20 bigfile
-rwxrwxrwx. 1 root root      1392 Feb  5 09:24 dingding.sh

Popen类的对象方法

名称 功能
poll() 检查是否结束,设置返回值
wait() 等待结束,设置返回值
communicate() 参数是标准输入,返回标准输出和标准出错
send_signal() 发动信号(主要指linux下有用)
terminate() 终止进程,unix对应的SIGTERM信号,windows下调用api函数TerminateProcess()
kill() 杀死进程(unix对应SIGKILL信号),windows下同上
stdin
stdout
stderr
参数中指定PIPE时有用
pid 进程id
returncode 进程返回值

补充:其他方法

1、subeprocess.call(*args,**kwargs): call()方法调用Popen()执行程序,并且等待它执行完成
2、subpeocess.check_call(*args, **kwargs): 调用上面的call(),如果返回值非零,返回异常
3、subprocess.check_output(*args, **kwargs) : 调用Popen()执行程序,并返回标准输出

二、补充os模块执行外部命令

1、os.system()方法

示例:

[root@localhost python]# cat 4.py
#!/bin/env python3
import os
# 变量ret接收命令执行后的返回值
ret = os.system('ls -l /ltp |head -2')
print("\n执行成功" if ret == 0 else "\n执行失败")

执行结果

[root@localhost python]# ./4.py
total 184980
-rw-r--r--. 1 root root     10865 May  8 16:21 123.txt

执行成功

2、os.popen()用法

与subprocess.Popen()类似,就不写了

补充:subprocess.run()和subprocess.Popen()的执行结果是写入到缓存的,可以执行结束后打印结果,不会实时在终端输出;而os.system()是实时输出到终端界面的;

以上就是Python执行外部命令subprocess的详细内容,更多关于Python执行外部命令的资料请关注其它相关文章!

    您感兴趣的教程

    在docker中安装mysql详解

    本篇文章主要介绍了在docker中安装mysql详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编...

    详解 安装 docker mysql

    win10中文输入法仅在桌面显示怎么办?

    win10中文输入法仅在桌面显示怎么办?

    win10系统使用搜狗,QQ输入法只有在显示桌面的时候才出来,在使用其他程序输入框里面却只能输入字母数字,win10中...

    win10 中文输入法

    一分钟掌握linux系统目录结构

    这篇文章主要介绍了linux系统目录结构,通过结构图和多张表格了解linux系统目录结构,感兴趣的小伙伴们可以参考一...

    结构 目录 系统 linux

    PHP程序员玩转Linux系列 Linux和Windows安装

    这篇文章主要为大家详细介绍了PHP程序员玩转Linux系列文章,Linux和Windows安装nginx教程,具有一定的参考价值,感兴趣...

    玩转 程序员 安装 系列 PHP

    win10怎么安装杜比音效Doby V4.1 win10安装杜

    第四代杜比®家庭影院®技术包含了一整套协同工作的技术,让PC 发出清晰的环绕声同时第四代杜比家庭影院技术...

    win10杜比音效

    纯CSS实现iOS风格打开关闭选择框功能

    这篇文章主要介绍了纯CSS实现iOS风格打开关闭选择框,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作...

    css ios c

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的办法

    Win7如何给C盘扩容 Win7系统电脑C盘扩容的

    Win7给电脑C盘扩容的办法大家知道吗?当系统分区C盘空间不足时,就需要给它扩容了,如果不管,C盘没有足够的空间...

    Win7 C盘 扩容

    百度推广竞品词的投放策略

    SEM是基于关键词搜索的营销活动。作为推广人员,我们所做的工作,就是打理成千上万的关键词,关注它们的质量度...

    百度推广 竞品词

    Visual Studio Code(vscode) git的使用教程

    这篇文章主要介绍了详解Visual Studio Code(vscode) git的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...

    教程 Studio Visual Code git

    七牛云储存创始人分享七牛的创立故事与

    这篇文章主要介绍了七牛云储存创始人分享七牛的创立故事与对Go语言的应用,七牛选用Go语言这门新兴的编程语言进行...

    七牛 Go语言

    Win10预览版Mobile 10547即将发布 9月19日上午

    微软副总裁Gabriel Aul的Twitter透露了 Win10 Mobile预览版10536即将发布,他表示该版本已进入内部慢速版阶段,发布时间目...

    Win10 预览版

    HTML标签meta总结,HTML5 head meta 属性整理

    移动前端开发中添加一些webkit专属的HTML5头部标签,帮助浏览器更好解析HTML代码,更好地将移动web前端页面表现出来...

    移动端html5模拟长按事件的实现方法

    这篇文章主要介绍了移动端html5模拟长按事件的实现方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家...

    移动端 html5 长按

    HTML常用meta大全(推荐)

    这篇文章主要介绍了HTML常用meta大全(推荐),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参...

    cdr怎么把图片转换成位图? cdr图片转换为位图的教程

    cdr怎么把图片转换成位图? cdr图片转换为

    cdr怎么把图片转换成位图?cdr中插入的图片想要转换成位图,该怎么转换呢?下面我们就来看看cdr图片转换为位图的...

    cdr 图片 位图

    win10系统怎么录屏?win10系统自带录屏详细教程

    win10系统怎么录屏?win10系统自带录屏详细

    当我们是使用win10系统的时候,想要录制电脑上的画面,这时候有人会想到下个第三方软件,其实可以用电脑上的自带...

    win10 系统自带录屏 详细教程

    + 更多教程 +
    ASP编程JSP编程PHP编程.NET编程python编程