Python 编程过程中经常会用到系统命令,本文记录实现方法。
系统命令 {#系统命令}
- 作为胶水语言,Python可以很方便的执行系统命令,Python3中常用的执行操作系统命令有以下方式
- os.system()
- os.popen()
- subprocess 模块
os.system {#os-system}
-
执行命令但无法获取取命令输出时,可以使用
os.system
-
os.system()
是C语言system()
函数的封装,返回命令的退出状态码,命令执行结果输出到标准输出(stdout/窗口)。 -
system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程。
-
其返回值是指令运行后返回的状态码,0表示指令成功执行,1表示失败,256表示没有返回结果,该方法适用于系统命令不需要输出内容的场景。
-
用法:
- 示例:
os.popen {#os-popen}
-
这种调用方式是通过管道的方式来实现,这个函数的返回值是一个文件对象,可以读或者写(由mode决定,mode默认是'r')。如果mode为'r',调用该对象的
read()
或readlines()
方法可以读取输出内容。 -
用法:
os.system(cmd)
或os.popen(cmd)
,前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。- 示例:
subprocess {#subprocess}
-
subprocess模块是python从2.4版本开始引入的模块,主要用来取代 一些旧的模块方法,如os.system、os.spawn、os.popen、commands.*等。官方推荐使用该模块执行系统命令,subprocess模块通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。
好处在于:运用对线程的控制和监控,将返回的结果赋于一变量,便于程序的处理。
subprocess.Popen() {#subprocess-Popen}
使用Popen可以创建进程,并与进程进行复杂的交互。
- 用法:
- 在一些复杂场景中,我们需要将一个进程的执行输出作为另一个进程的输入。在另一些场景中,我们需要先进入到某个输入环境,然后再执行一系列的指令等。这个时候我们就需要使用到suprocess的Popen()方法。该方法有以下参数
| 参数 | 作用 | |--------------------|-------------------------------------------| | args | 一般是一个字符串,是要执行的shell命令内容 | | bufsize | 设置缓冲,负数表示系统默认缓冲,0表示无缓冲,正数表示自定义缓冲行数 | | stdin | 程序的标准输入句柄,NONE表示不进行重定向,继承父进程,PIPE表示创建管道 | | stdout | 程序的标准输出句柄,参数意义同上 | | stderr | 程序的标准错误句柄,参数意义同上,特殊,可以设置成STDOUT,表示与标准输出一致 | | shell | 为True时,表示将通过shell来执行 | | cwd | 用来设置当前子进程的目录 | | env | 用于指定子进程的环境变量。如果env=None,则默认从父进程继承环境变量 | | universal_newlines | 不同系统的的换行符不同,当该参数设定为true时,则表示使用\n作为换行符。 |
- Popen方法:
- 1、Popen.poll():用于检查子进程是否已经结束。设置并返回returncode属性。
- 2、Popen.wait():等待子进程结束。设置并返回returncode属性。
- 3、Popen.communicate(input=None):与子进程进行交互。向stdin发送数据,或从stdout和stderr中读取数据。可选参数input指定发送到子进程的参数。Communicate()返回一个元组:(stdoutdata, stderrdata)。注意:如果希望通过进程的stdin向其发送数据,在创建Popen对象的时候,参数stdin必须被设置为PIPE。同样,如果希望从stdout和stderr获取数据,必须将stdout和stderr设置为PIPE。
- 4、Popen.send_signal(signal):向子进程发送信号。
- 5、Popen.terminate():停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。
- 6、Popen.kill():杀死子进程。
- 7、Popen.stdin:如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。
- 8、Popen.stdout:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。
- 9、Popen.stderr:如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。
- 10、Popen.pid:获取子进程的进程ID。
- 11、Popen.returncode:获取进程的返回值。如果进程还没有结束,返回None。
- 12、subprocess.call(*popenargs, **kwargs):运行命令。该函数将一直等待到子进程运行结束,并返回进程的returncode。文章一开始的例子就演示了call函数。如果子进程不需要进行交互,就可以使用该函数来创建。
- 13、subprocess.check_call(*popenargs, **kwargs):与subprocess.call(*popenargs, **kwargs)功能一样,只是如果子进程返回的returncode不为0的话,将触发CalledProcessError异常。在异常对象中,包括进程的returncode信息
- 示例
注意 {#注意}
- 在shell=True这个参数,不写的时候默认是False,shell默认为/bin/sh。如果 args是一个字符串,则该字符串指定要通过shell执行的命令。
- 当需要设置shell=True时(当False时,arges是列表,第一个参数是shell命令,后面的都是参数',' 隔开),须把args设为string,空格隔开,如下
subprocess.call() {#subprocess-call}
-
执行指定的命令, 返回命令执行状态, 功能类似os.system(cmd),参数shell默认为False
-
用法:
- 示例:
subprocess.run() {#subprocess-run}
-
python3.5中新增的函数, 执行指定的命令, 等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。run默认不会返回输出,只返回命令和执行状态。
-
用法:
subprocess.getstatusoutput() {#subprocess-getstatusoutput}
-
执行cmd命令,返回一个元组(命令执行状态,命令执行结果输出)。
-
返回状态码和结果,0表示成功
-
示例:
subprocess.check_call() {#subprocess-check-call}
-
与call方法类似,不同在于如果命令行执行成功,check_call返回返回码0,否则抛出subprocess.CalledProcessError异常。
subprocess.CalledProcessError异常包括returncode、cmd、output等属性,其中returncode是子进程的退出码,cmd是子进程的执行命令,output为None。 -
用法
- 示例:
参考资料 {#参考资料}
- https://www.cnblogs.com/lsdb/p/13068187.html
- https://docs.python.org/3/library/os.html#os.system
- https://zhuanlan.zhihu.com/p/95130482
- https://zhuanlan.zhihu.com/p/329957363
文章链接:
https://www.zywvvd.com/notes/coding/python/python-sys-command/python-sys-command/