心得: 愿生命中的每一次相遇都应该去珍惜,我愿用更优秀的自己去迎接未来的你~
subprocess模块:
在linux系统中,subprocess模块可以帮助我们生成子进程,并可以通过管道来连接他们的输入输出,并获取返回值,进而达到通信.这么模块有意取代os模块.
来看看os模块的通信功能:
1 os.system()
直接运行shell command,进行交互
import os
>>> os.system("df -TH")
文件系统 类型 容量 已用 可用 已用% 挂载点
udev devtmpfs 4.1G 0 4.1G 0% /dev
tmpfs tmpfs 825M 9.9M 815M 2% /run
/dev/nvme0n1p6 ext4 108G 8.1G 95G 8% /
tmpfs tmpfs 4.2G 308k 4.2G 1% /dev/shm
tmpfs tmpfs 5.3M 4.1k 5.3M 1% /run/lock
tmpfs tmpfs 4.2G 0 4.2G 0% /sys/fs/cgroup
/dev/loop0 squashfs 94M 94M 0 100% /snap/core/7713
/dev/nvme0n1p1 vfat 101M 48M 54M 48% /boot/efi
tmpfs tmpfs 825M 4.1k 825M 1% /run/user/108
tmpfs tmpfs 825M 58k 825M 1% /run/user/1000
0
返回值 0代表执行成功
1.2 os.popen()
执行shell command ,并通过管道存储结果
>>> import os
>>> r=os.popen("ls -l")
>>> r
<os._wrap_close object at 0x7fe8f64974a8>
>>> print(r.read())
总用量 23932
-rwxrwxrwx 1 tianjain tianjain 1887 9月 29 23:05 0926.py
-rwxr----- 1 tianjain tianjain 1618 9月 25 22:42 0_9.py
-rw-rw-r-- 1 tianjain tianjain 546 9月 26 22:35 123.py
drwxrwxr-x 5 tianjain tianjain 4096 9月 24 23:13 apple
-rwxrwxrwx 1 tianjain tianjain 1095 9月 13 12:15 creatfile.sh
>>> print(r.read())
可以看到返回值只能读取一次,第二次调用会为空
2 subprocess.run()
subprocess.run(args[, stdout, stderr, shell …])
import subprocess
>>> subprocess.run(["ls","-l"])
总用量 23932
-rwxrwxrwx 1 tianjain tianjain 1887 9月 29 23:05 0926.py
-rwxr----- 1 tianjain tianjain 1618 9月 25 22:42 0_9.py
-rw-rw-r-- 1 tianjain tianjain 546 9月 26 22:35 123.py
drwxrwxr-x 5 tianjain tianjain 4096 9月 24 23:13 apple
自己解析加shell=True
>>> subprocess.run("ls -l",shell=True)
总用量 23932
-rwxrwxrwx 1 tianjain tianjain 1887 9月 29 23:05 0926.py
-rwxr----- 1 tianjain tianjain 1618 9月 25 22:42 0_9.py
-rw-rw-r-- 1 tianjain tianjain 546 9月 26 22:35 123.py
2.1 subprocess.call()
subprocess.call(args[, stdout, …])
返回值为命令执行的状态码
2.2 subprocess.check_call()
subprocess.check_call(args[, stdout, …])
返回值为命令执行的状态码,执行成功返回0,失败则抛出异常
2.3 subprocess.check_output()
subprocess.check_output(args[, stderr, …])
>>> a=subprocess.check_output("pwd")
>>> a
b'/home/tianjain\n'
若执行成功,则函数返回值为命令输出结果;若执行失败,则抛出异常;返回结果为字节形式
2.4 subprocess.getoutput()
返回字符串结果
>>> a=subprocess.getoutput("pwd")
>>> a
'/home/tianjain'
>>> print(a)
/home/tianjain
2.5 subprocess.getstatusoutput()
返回元祖形式,第一个为命令执行状态,第二为结果
>>> a=subprocess.getstatusoutput("pwd")
>>> a
(0, '/home/tianjain')
>>> print(a)
(0, '/home/tianjain')
>>> a[1]
'/home/tianjain'
看看具体用用法:
# subprocess.run使用
def subprocess_run():
print("**** subprocess.run ****")
print("----------")
result1 = subprocess.run(["adb", "devices"])
print("result1:", result1)
print("----------")
result2 = subprocess.run("adb devices", shell=True, check=True)
print("result2:", result2)
print("----------")
result3 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE)
print("result3:", result3)
print(type(result3))
subprocess_run()
"""结果
**** subprocess.run ****
----------
List of devices attached
338b123f0504 device
result1: CompletedProcess(args=['adb', 'devices'], returncode=0)
----------
List of devices attached
338b123f0504 device
result2: CompletedProcess(args='adb devices', returncode=0)
----------
result3: CompletedProcess(args=['adb', 'devices'], returncode=0, stdout=b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n')
<class 'subprocess.CompletedProcess'>
"""
# subprocess.call使用
def subprocess_call():
print("**** subprocess.call ****")
print("----------")
result1 = subprocess.call(["adb", "devices"])
print("result1:", result1)
print("----------")
result2 = subprocess.call(["adb", "devices"], stdout=subprocess.PIPE)
print("result2:", result2)
subprocess_call()
"""结果
**** subprocess.call ****
----------
List of devices attached
338b123f0504 device
result1: 0
----------
result2: 0
"""
# subprocess.check_call
def subprocess_check_call():
print("**** subprocess.check_call ****")
print("----------")
result1 = subprocess.check_call(["adb", "devices"])
print("result1:", result1)
print("----------")
result2 = subprocess.check_call(["adb", "devices"], stdout=subprocess.PIPE)
print("result2:", result2)
subprocess_check_call()
"""结果
**** subprocess.check_call ****
----------
List of devices attached
338b123f0504 device
result1: 0
----------
result2: 0
"""
# subprocess.check_output
def subprocess_check_output():
print("**** subprocess.check_output ****")
print("----------")
result1 = subprocess.check_output(["adb", "devices"])
print("result1:", result1)
print("----------")
result2 = subprocess.run(["adb", "devices"], stdout=subprocess.PIPE).stdout
print("result2:", result2)
subprocess_check_output()
"""结果
**** subprocess.check_output ****
----------
result1: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'
----------
result2: b'List of devices attached \r\n338b123f0504\tdevice\r\n\r\n'
"""
3 subprocess.Popen()
subprocess.Popen类用于在一个新进程中执行一个子程序,上述subprocess函数均是基于subprocess.Popen类
3.1标准输出 stdout
import subprocess
res=subprocess.Popen("/home/tianjain/lianxi/hello.sh",shell=True,stdout=subprocess.PIPE)#通道
print(res.stdout.read().decode(encoding="utf-8"))
res.stdout.close() #关闭通道
print(res)
输出的字符为字节格式,需要转换为字符格式
PIPE管道相当于连接执行命令的结果和stdout.read的通道
输出:
tianjain@tianjain-TM1701:~/lianxi$ python3 hello.py
Hello world
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
1*10=10 2*10=20 3*10=30 4*10=40 5*10=50 6*10=60 7*10=70 8*10=80 9*10=90 10*10=100
<subprocess.Popen object at 0x7fb8daa1d7b8>
3.2 poll()
检查命令执行状态,执行完毕返回0
print(res.poll)
0
3.3 wait()
等待命令执行完毕,返回状态
print(res.wait())
0
3.4 terminate()
结束进程,结束之后读出的结果为空
res.terminate()
3.5 pid
获取进程的pid
print(res.pid)
5178
import subprocess
res=subprocess.Popen("/home/tianjain/lianxi/hello.sh",stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#print(res.terminate()) #结束进程
print(res.stdout.read().decode(encoding="utf-8"))
print(res.pid)
print(res.wait())
print(res.poll)
res.stdout.close() #关闭通道
print(res)
输出
tianjain@tianjain-TM1701:~/lianxi$ python3 hello.py
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
1*10=10 2*10=20 3*10=30 4*10=40 5*10=50 6*10=60 7*10=70 8*10=80 9*10=90 10*10=100
5223 #pid
0 #wait 返回值
0 #status 返回值
<subprocess.Popen object at 0x7f963bb107f0> #对象地址