18 subprocess模块(跟操做系统交互)

一、基本概念介绍

咱们常常须要经过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程以外的,python

每执行一条命令,就是发起一个新进程,经过python调用系统命令或脚本的模块在python2有os.system,linux

早期的Python版本中,咱们主要是经过os.system()、os.popen().read()等函数来执行命令行指令的,另外还有一个不多使用的commands模块。shell

可是从Python 2.4开始官方文档中建议使用的是subprocess模块,因此os模块和commands模块的相关函数在这里只提供一个简单的使用示例,咱们重要要介绍的是subprocess模块。windows

commands.getstatusoutput()函数实例

须要注意的是commands模块不支持windows平台,所以该实例是在Linux平台下执行的函数

二、subprocess模块中经常使用的函数

官方推出了subprocess,目地是提供统一的模块来实现对系统命令或脚本的调用ui

三种执行命令的方法spa

    • subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推荐命令行

    • subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面实现的内容差很少,另外一种写法3d

    • subprocess.Popen() #上面各类方法的底层封装code

 并链接到进程的输入/输出/错误输出管道,并获取进程的返回值。

 

In Windows , to use echo in subprocess, you would need to use shell=True . 

This is because echo is not a separate executable, but rather a built-in command for the windows command line.

Example - process1 = subprocess.Popen(command1,stdout=subprocess.PIPE,shell=True)

 

 

参数说明: args: 要执行的shell命令,默认应该是一个字符串序列,如['df', '-Th']或('df', '-Th'),也能够是一个字符串,如'df -Th',可是此时须要把shell参数的值置为True。
window下执行shell=True加上 shell: 若是shell为True,那么指定的命令将经过shell执行。若是咱们须要访问某些shell的特性,如管道、文件名通配符、环境变量扩展功能,这将是很是有用的。
固然,python自己也提供了许多相似shell的特性的实现,如glob、fnmatch、os.walk()、os.path.expandvars()、os.expanduser()和shutil等。
check: 若是check参数的值是True,且执行命令的进程以非0状态码退出,则会抛出一个CalledProcessError的异常,且该异常对象会包含 参数、退出状态码、以及stdout和stderr(若是它们有被捕获的话)。
stdout, stderr:   run()函数默认不会捕获命令执行结果的正常输出和错误输出,若是咱们向获取这些内容须要传递subprocess.PIPE,而后能够经过返回的CompletedProcess类实例的stdout和stderr属性或捕获相应的内容;   call()和check_call()函数返回的是命令执行的状态码,而不是CompletedProcess类实例,因此对于它们而言,stdout和stderr不适合赋值为subprocess.PIPE;   check_output()函数默认就会返回命令执行结果,因此不用设置stdout的值,若是咱们但愿在结果中捕获错误信息,能够执行stderr
=subprocess.STDOUT。
input: 该参数是传递给Popen.communicate(),一般该参数的值必须是一个字节序列,若是universal_newlines
=True,则其值应该是一个字符串。
universal_newlines: 该参数影响的是输入与输出的数据格式,好比它的值默认为False,此时stdout和stderr的输出是字节序列;当该参数的值设置为True时,stdout和stderr的输出是字符串。

 

三、run()方法

 PIPE管道的意思,window下执行shell=True加上

print(subprocess.run(['dir'], shell = True, stdout = subprocess.PIPE))

标准写法 subprocess.run(['df','-h'],stderr=subprocess.PIPE,stdout=subprocess.PIPE,check=True) 涉及到管道|的命令须要这样写 subprocess.run('df -h|grep disk1',shell=True) #shell=True的意思是这条命令直接交给系统去执行,不须要python负责解析

四、call()方法

linux系统下执行:

#
执行命令,返回命令执行状态 , 0 or 非0 >>> retcode = subprocess.call(["ls", "-l"]) #执行命令,若是命令结果为0,就正常返回,不然抛异常 >>> subprocess.check_call(["ls", "-l"]) 0 #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') #接收字符串格式命令,并返回结果 >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res >>> res=subprocess.check_output(['ls','-l']) >>> res b'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n'

五、Popen()方法

 
 

经常使用参数:

 
 
  • args:shell命令,能够是字符串或者序列类型(如:list,元组)
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行以前被调用
  • shell:同上
  • cwd:用于设置子进程的当前目录
  • env:用于指定子进程的环境变量。若是env = None,子进程的环境变量将从父进程中继承。
 
 

下面这2条语句执行会有什么区别?

a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE) a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
 
 

区别是Popen会在发起命令后马上返回,而不等命令执行结果。这样的好处是什么呢?

 
 

若是你调用的命令或脚本 须要执行10分钟,你的主程序不需卡在这里等10分钟,能够继续往下走,干别的事情,每过一会,经过一个什么方法来检测一下命令是否执行完成就行了。

 

 

Popen调用后会返回一个对象,能够经过这个对象拿到命令执行结果或状态等,该对象有如下方法 poll()  Check if child process has terminated. Returns returncode wait() Wait for child process to terminate. Returns returncode attribute. terminate()终止所启动的进程Terminate the process with SIGTERM kill() 杀死所启动的进程 Kill the process with SIGKILL  communicate()与启动的进程交互,发送数据到stdin,并从stdout接收输出,而后等待任务结束 >>> a = subprocess.Popen('python3 guess_age.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True) >>> a.communicate(b'22') (b'your guess:try bigger\n', b'')

send_signal(signal.xxx)发送系统信号

pid 拿到所启动进程的进程号

相关文章
相关标签/搜索