加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

subprocess.Popen模块

发布时间:2020-12-15 23:09:20 所属栏目:安全 来源:网络整理
导读:该类用于在一个新的进程中执行一个子程序。subprocess模块底层的进程创建和管理是由Popen类来处理的。 1.subprocess.Popen的构造函数 class subprocess.Popen(args,bufsize=-1,executable=None,stdin=None,stdout=None,stderr= None,preexec_fn =None,close_

该类用于在一个新的进程中执行一个子程序。subprocess模块底层的进程创建和管理是由Popen类来处理的。

1.subprocess.Popen的构造函数

class subprocess.Popen(args,bufsize=-1,executable=None,stdin=None,stdout=None,stderr=None,preexec_fn=None,close_fds=True,shell=False,cwd=None,env=None,universal_newlines=False,startup_info=None,creationflags=0,restore_signals=True,start_new_session=False,pass_fds=())

参数说明:
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,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"],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

?

实例5:

import subprocess

‘‘‘
sh-3.2# ls /Users/egon/Desktop |grep txt$
mysql.txt
tt.txt
事物.txt
‘‘‘

res1=subprocess.Popen(ls /Users/jieli/Desktop |grep txt$,shell=True,stdout=subprocess.PIPE)
print(res1.stdout.read().decode(utf-8)) #等同于上面,也可以一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep res1=subprocess.Popen(ls /Users/jieli/Desktop,stdout=subprocess.PIPE) res=subprocess.Popen(grep txt$,stdin=res1.stdout,stdout=subprocess.PIPE)
print(res.stdout.read().decode(utf-8)) #windows下: # dir | findstr ‘test*‘ # dir | findstr ‘txt$‘ import subprocess res1=subprocess.Popen(rdir C:UsersAdministratorPycharmProjectstest函数备课,stdout=subprocess.PIPE) res=subprocess.Popen(findstr test*,stdout=subprocess.PIPE)
print(res.stdout.read().decode(gbk)) #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读