第二十三篇 subprocess模块 python交互linux系统,进程和管道输入输出用法

心得: 愿生命中的每一次相遇都应该去珍惜,我愿用更优秀的自己去迎接未来的你~

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 929 23:05 0926.py
-rwxr-----  1 tianjain tianjain     1618 925 22:42 0_9.py
-rw-rw-r--  1 tianjain tianjain      546 926 22:35 123.py
drwxrwxr-x  5 tianjain tianjain     4096 924 23:13 apple
-rwxrwxrwx  1 tianjain tianjain     1095 913 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 929 23:05 0926.py
-rwxr-----  1 tianjain tianjain     1618 925 22:42 0_9.py
-rw-rw-r--  1 tianjain tianjain      546 926 22:35 123.py
drwxrwxr-x  5 tianjain tianjain     4096 924 23:13 apple

自己解析加shell=True

>>> subprocess.run("ls -l",shell=True)
总用量 23932
-rwxrwxrwx  1 tianjain tianjain     1887 929 23:05 0926.py
-rwxr-----  1 tianjain tianjain     1618 925 22:42 0_9.py
-rw-rw-r--  1 tianjain tianjain      546 926 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>  #对象地址

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值