您的位置:首页技术文章
文章详情页

Python执行外部命令subprocess的使用详解

【字号: 日期:2022-06-19 17:11:53浏览:3作者:猪猪
目录一、了解subprocess1、subprocess.run()方法2、Popen类二、补充os模块执行外部命令1、os.system()方法2、os.popen()用法一、了解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 python3import subprocessb=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.txtprint(b) # 执行该run函数后返回的CompletedProcess类# CompletedProcess(args=’ls -l /ltp | head -2’, returncode=0)print(b.args) # 打印出CompletedProcess类的agrs属性值,就是执行的shell命令# ls -l /ltp | head -2print(b.returncode) # 打印命令执行的状态码# 0

结果展示

[root@localhost python]# ./1.pytotal 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 python3import subprocessb = subprocess.run(['ls', '-l', '/ltp'])print(b)print(b.args)print(b.returncode)

执行结果

[root@localhost python]# ./2.pytotal 10865-rw-r--r--. 1 root root 10865 May 8 16:21 123.txtCompletedProcess(args=[’ls’, ’-l’, ’/ltp’], returncode=0)[’ls’, ’-l’, ’/ltp’]0

3.捕获脚本输出

如果需要采集命令执行的结果,可以传入参数stdout=subprocess.PIPE

[root@localhost python]# cat 3.py#!/bin/env python3import subprocess# 传入stdout=subprocess.PIPE参数即可b=subprocess.run('ls -l /ltp | head -2', shell=True, stdout=subprocess.PIPE)print(b.stdout)

结果显示

[root@localhost python]# ./1.pyb’total 184980n-rw-r--r--. 1 root root 10865 May 8 16:21 123.txtn’

4.检测异常

示例1:模拟renturncode值不为0

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

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

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

[root@localhost python]# ./1.pyls: cannot access /123: No such file or directoryTraceback (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 python3import subprocessb=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.pyTraceback (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 python3import subprocessobj = 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_infoprint(result)[root@localhost python]# ./3.pytotal 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.shdrwxr-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 python3import os# 变量ret接收命令执行后的返回值ret = os.system(’ls -l /ltp |head -2’)print('n执行成功' if ret == 0 else 'n执行失败')

执行结果

[root@localhost python]# ./4.pytotal 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执行外部命令的资料请关注好吧啦网其它相关文章!

标签: Python 编程
相关文章: