gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Python执行外部命令subprocess的使用详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、了解subprocess

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

1、subprocess.run()方法

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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命令 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[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.使用列表方式执行 。

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

?
1
2
3
4
5
6
#!/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
?
1
2
3
4
5
6
7
[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时,就会抛出异常 。

?
1
2
3
4
5
[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 类型报错 。

?
1
2
3
4
5
6
7
8
9
[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 异常 。

?
1
2
3
4
5
6
7
[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类的构造函数 。

  。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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”]) 。

示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[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()执行程序,并返回标准输出 。

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

1、os.system()方法

示例:

?
1
2
3
4
5
6
[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执行外部命令的资料请关注我其它相关文章! 。

原文链接:https://blog.csdn.net/CN_LiTianpeng/article/details/116736321 。

最后此篇关于Python执行外部命令subprocess的使用详解的文章就讲到这里了,如果你想了解更多关于Python执行外部命令subprocess的使用详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com