python3之subprocess常见⽅法使⽤⼀、常见subprocess⽅法
1、statusoutput(cmd)
官⽅解释:
Return (exitcode, output) of executing cmd in a shell.
Execute the string 'cmd' in a shell with 'check_output' and
return a 2-tuple (status, output). The locale encoding is used
to decode the output and process newlines.
cmd可以直接执⾏shell命令,⽽不需要cmd命令以列表输⼊----statusoutput("cat /proc/meminfo")
返回值包含cmd的执⾏状态和执⾏结果,可以直接赋值给某个变量
实例:
>>> ret = utput('ls -l')
>>> print(ret)
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
createprocessadrwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> retcode, output = statusoutput('ls -l')
>>> print(retcode)
>>> print(output)
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> retcode, output = statusoutput('ls -l /test')
>>> print(retcode)
2
>>> print(output)
ls: ⽆法访问/test: 没有那个⽂件或⽬录
2、utput(cmd)
官⽅解释:
Return output (stdout or stderr) of executing cmd in a shell.
Like getstatusoutput(), except the exit status is ignored and the return
value is a string containing the command's output
cmd可以直接执⾏shell命令,⽽不需要cmd命令以列表输⼊---utput("cat /proc/meminfo")
返回值包含cmd的执⾏结果,可以直接赋值给某个变量
功能和getstatusoutput类似
3、subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs))
Run command with arguments and return a CompletedProcess instance.  执⾏传⼊命令参数后,返回CompletedProcess实例
The returned instance will have attributes args, returncode, stdout and
stderr. By default, stdout and stderr are not captured, and those attributes
will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.
check等于True的时候,当执⾏状态不是0时,会抛出CalledProcessError异常提⽰
传⼊命令参数时,需要以多个命令拆分按照列表形式传⼊:subprocess.run(['df', '-h'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
如果传⼊参数同时传⼊shell=True,则传⼊⼀个字符串args,shell命令⽽不是待执⾏的shell命令序列
实例:
>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)
>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
4、subprocess.call()
官⽅解释:
Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute
传⼊shell命令参数格式subprocess.check_call(["ls", "-l"])
如果传⼊参数同时传⼊shell=True,则可以传⼊⼀个字符串shell命令⽽不是待执⾏的shell命令列表--subprocess.check_call("exit 1", shell=True)返回参数仅返回执⾏状态码,可通过把结果复制给某个变量查看,如果直接在linux下python编译器执⾏该命令会直接显⽰命令执⾏的结果
实例:
>>> subprocess.call(['ls',  '-l'])
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> subprocess.call('ls -l', shell=True)
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> subprocess.call(['ls',  '-l'], stdout=subprocess.DEVNULL)
>>> subprocess.call(['ls',  '-l', '/test'])
ls: ⽆法访问/test: 没有那个⽂件或⽬录
2
5、subprocess.check_call()
官⽅解释:
Run command with arguments.  Wait for command to complete.  If
the exit code was zero then return, otherwise raise
CalledProcessError.  The CalledProcessError object will have the
return code in the returncode attribute.
check_call基本和call功能⼀样,只是增加了返回状态码校验,如果执⾏状态码是0,则返回0,否则抛出异常
实例:
>>> subprocess.check_call(['ls',  '-l'])
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> subprocess.check_call('ls -l', shell=True)
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
>>> subprocess.check_call('ls -l /test', shell=True)
ls: ⽆法访问/test: 没有那个⽂件或⽬录
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 557, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command 'ls -l /test' returned non-zero exit status 2
6、subprocess.check_output()
官⽅解释:
Run command with arguments and return its output.
If the exit code was non-zero it raises a CalledProcessError.  The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
执⾏命令,如果状态码是0,则返回执⾏结果,否则抛出异常--
subprocess.check_output(["ls", "-l"])
如果传⼊参数同时传⼊shell=True,则可以传⼊⼀个字符串shell命令⽽不是待执⾏的shell命令列表--
subprocess.check_call("exit 1", shell=True)
返回值包含cmd的执⾏结果,可以直接赋值给某个变量
实例:
>>> ret = subprocess.check_output(['ls',  '-l'])
>>> print(ret)
b' \xe5\x85\xac\xe5\x85\xb1\xe7\x9a\x84\ndrwxr-xr-x  2 wader wader  4096 12\xe6\x9c\x88  7  2015 \xe6\xa8\xa1\xe6\x9d\xbf\ndrwxr-xr-x  2 wader wader  4096 12\xe6\x9c\x88  7  2015 \xe8\xa7\x86\xe9\xa2\x91\ndrwxr-xr-x  2 wader wader  40 >>> ret = subprocess.check_output(['ls',  '-l'], universal_newlines=True)
>>> print(ret)
总⽤量 160
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 公共的
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 模板
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 视频
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 图⽚
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⽂档
drwxr-xr-x  2 wader wader  4096  4⽉ 13  2016 下载
drwxr-xr-x  2 wader wader  4096 12⽉  7  2015 ⾳乐
drwxr-xr-x  7 wader wader  4096  5⽉ 26  2016 桌⾯
⼆、subprocess.Popen()类--⽤于执⾏复杂的系统命令
该类⽤于在⼀个新的进程中执⾏⼀个⼦程序。前⾯我们提到过,上⾯介绍的这些函数都是基于subprocess.Popen类实现的,通过使⽤这些被封装后的⾼级函数可以很⽅⾯的完成
⼀些常见的需求。由于subprocess模块底层的进程创建和管理是由Popen类来处理的,因此,当我们⽆法通过上⾯哪些⾼级函数来实现⼀些不太常见的功能时就可以通过
subprocess.Popen类提供的灵活的api来完成。
1、subprocess.Popen的构造函数
def__init__(self, args, bufsize=-1, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
shell=False, cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=(), *, encoding=None, errors=None)
构造函数详细参数说明和其他实现过程可以参考对应subprocess库⽂件
参数说明:
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异常。
Popenmunicate(input=None, timeout=None)该⽅法可⽤来与进程进⾏交互,⽐如发送数据到stdin,从stdout和stderr读取数据,直到到达⽂件末尾。
Popen.send_signal(signal)发送指定的信号给这个⼦进程。
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(ad())
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, stdout=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 = objmunicate()
>>> print(out)
1
2
3
>>> print(err)
实例3
>>> obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> out,err = objmunicate(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 = p2municate()
>>> 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
三、总结
那么我们到底该⽤哪个模块、哪个函数来执⾏命令与系统及系统进⾏交互呢?下⾯我们来做个总结:
1、如果你的应⽤使⽤的Python 2.4以上,但是是Python 3.5以下的版本,Python官⽅给出的建议是使⽤subprocess.call()函数。Python 2.5中新增了⼀个subprocess.check_call()函数,Python 2.7中新增了⼀个subprocess.check_output()函数,这两个函数也可以按照需求进⾏使⽤
2、如果你的应⽤使⽤的是Python 3.5及以上的版本(⽬前应该还很少),Python官⽅给出的建议是尽量使⽤subprocess.run()函数
3、当subprocess.call()、subprocess.check_call()、subprocess.check_output()和subprocess.run()这些⾼级函数⽆法满⾜需求时,我们可以使⽤subprocess.Popen类来实现我们需要的复杂功能
不过经过个⼈试验认为getoutput、getstatusoutput⽅法使⽤⽐较便捷,subprocess适合个性化的执⾏

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。