抽空了解了一下python的subprocess包,简单记下学习记录。subprocess是python中的一个子进程包,可以在运行python的时候打开一个子进程来运行另一个外部程序。通过该包的功能,可以调用一些shell命令以对操作系统简单操作。
subprocess定义了数个以不同方式创建子进程的函数,这里只简单记录一下。
subprocess.call(),通过此函数创建子进程后,父进程会等待子进程执行完成,并返回退出信息(returncode);
subprocess.Popen(), 通过此函数创建的子进程,父进程并不会等待子进程完成,除非子进程调用child.wait()方法。
# coding:utf-8
import subprocess
rc = subprocess.call(["ls", "-l"])
# print(rc)
print("aaa")
# 通过shell执行
out = subprocess.Popen("ls -l", shell=True)
# print out
print("test")
# total 24
# -rw-r--r-- 1 linshaokang staff 15 Jan 6 12:55 __init__.py
# -rw-r--r-- 1 linshaokang staff 187 Jan 16 12:27 test1.py
# -rw-r--r-- 1 linshaokang staff 769 Jan 6 13:18 test2.py
#
# aaa 父进程的字符串输出一直等待子进程完成后才输出
#
#
# test 同样的执行顺序,父进程并未等待子进程完成,直接输出test
#
# total 24
# -rw-r--r-- 1 linshaokang staff 15 Jan 6 12:55 __init__.py
# -rw-r--r-- 1 linshaokang staff 187 Jan 16 12:27 test1.py
# -rw-r--r-- 1 linshaokang staff 769 Jan 6 13:18 test2.py
其中call(),当然还有check_call(), check_output()函数其实是在Popen()上的一层封装,这些封装的目的只是方便简化我们使用子进程,如果有定制化的需求,可以使用Popen()函数。
子进程的文本流控制
child.stdin, child.stdout, child.stderr
在使用Popen创建子进程时,可以通过subprocess.PIPE将多个子进程连接起来组成一个管道以实现通讯。
# coding:utf-8
import subprocess
child1 = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE)
child2 = subprocess.Popen(["wc", "-l"], stdin=child1.stdout, stdout=subprocess.PIPE)
out = child2.stdout.read()
# out = child2.communicate()
print(out)
# subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。
# child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
#
# 要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。
child = subprocess.Popen(["cat"], stdin=subprocess.PIPE)
child.stdin.write("test1.py")
# child.communicate("test1.py")
# --------result-------------
# 4
# test1.py
通过subprocess可以扩展python的功能,类似于操作系统的某些操作应用等。