python subprocess模块
简介
subprocess最早在2.4版本引入。用来生成子进程,并可以通过管道连接他们的输入/输出/错误,以及获得他们的返回值。
subprocess用来替换多个旧模块和函数:
- os.system
- os.spawn*
- os.popen*
- popen2.*
- commands.*
运行python的时候,我们都是在创建并运行一个进程,linux中一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在python中,我们通过标准库中的subprocess包来fork一个子进程,并且运行一个外部的程序。subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
subprocess用法
subprocess.call
命令正确执行
# subprocess.call # 执行命令,打印执行输出并且返回执行状态,0表示执行成功,非0表示执行出现错误,其中shell为False时(默认为False),命令需要通过列表的传入,当shell为True时,可以直接传入命令 a = subprocess.call(['df', '-h'])
a = subprocess.call('df -h', shell=True)
print('-----------------------------')
print(a)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/disk1s1 190Gi 94Gi 93Gi 51% 832021 9223372036853943786 0% / devfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev /dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home /dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP --------------------------------- 0 #命令正确,执行状态为0
命令错误执行
a = subprocess.call(['df', '-1']) print(a)
64 df: illegal option -- 1 usage: df [-b | -H | -h | -k | -m | -g | -P] [-ailn] [-T type] [-t] [filesystem ...]
subprocess.check_call
命令执行正确的情况下,效果跟subprocess.call一样,但如果命令有误会直接抛出异常
a = subprocess.check_call(['df', '-h']) print(a)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/disk1s1 190Gi 94Gi 93Gi 51% 832051 9223372036853943756 0% / devfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev /dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home /dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP 0
命令错误
a = subprocess.check_call(['df', '-1']) print(a)
df: illegal option -- 1 usage: df [-b | -H | -h | -k | -m | -g | -P] [-ailn] [-T type] [-t] [filesystem ...] Traceback (most recent call last): File "/Users/zhangjin/2018/oldboy_python_lesson/oldboy_python2/模块/subprocess/subprocess模块.py", line 26, in <module> a = subprocess.check_call(['df', '-1']) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 328, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['df', '-1']' returned non-zero exit status 64.
subprocess.run
# 执行命令,打印执行输出,shell参数的含义跟call一样 a = subprocess.run(['df', '-h']) print(a)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/disk1s1 190Gi 94Gi 93Gi 51% 832046 9223372036853943761 0% / devfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev /dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home /dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP CompletedProcess(args=['df', '-h'], returncode=0)
subprocess.getstatusoutput
接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果
ret = subprocess.getstatusoutput('df -h') print(ret)
(0, 'Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n/dev/disk1s1 190Gi 94Gi 93Gi 51% 832049 9223372036853943758 0% /\ndevfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev\n/dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm\nmap -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net\nmap auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home\n/dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP')
subprocess.getoutput
接受字符串形式的命令,返回执行结果
ret = subprocess.getoutput('df -h') print(ret)
Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/disk1s1 190Gi 94Gi 93Gi 51% 832050 9223372036853943757 0% / devfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev /dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm map -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net map auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home /dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP
subprocess.check_output
接收一个命令和参数组成的元组(shell默认为False),返回bytes的执行结果
ret = subprocess.check_output(['df', '-h']) print(ret)
b'Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n/dev/disk1s1 190Gi 94Gi 93Gi 51% 832051 9223372036853943756 0% /\ndevfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev\n/dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm\nmap -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net\nmap auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home\n/dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP\n'
subprocess.Popen的用法
stdout
标准输出
res = subprocess.Popen('df -h', shell=True, stdout=subprocess.PIPE) print(res.stdout.read())
b'Filesystem Size Used Avail Capacity iused ifree %iused Mounted on\n/dev/disk1s1 190Gi 94Gi 93Gi 51% 832052 9223372036853943755 0% /\ndevfs 189Ki 189Ki 0Bi 100% 653 0 100% /dev\n/dev/disk1s4 190Gi 2.0Gi 93Gi 3% 2 9223372036854775805 0% /private/var/vm\nmap -hosts 0Bi 0Bi 0Bi 100% 0 0 100% /net\nmap auto_home 0Bi 0Bi 0Bi 100% 0 0 100% /home\n/dev/disk0s3 43Gi 27Gi 16Gi 63% 198929 4285707 4% /Volumes/BOOTCAMP\n'
stderr
标准错误
res = subprocess.Popen('df -1', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) print(res.stdout.read()) print(res.stderr.read())
b'' b'df: illegal option -- 1\nusage: df [-b | -H | -h | -k | -m | -g | -P] [-ailn] [-T type] [-t] [filesystem ...]\n'