利用python执行shell脚本 并动态传参 及subprocess基本使用
最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数
执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库
subprocess这个模块可以非常方便的启动一个子进程,并且控制其输入和输出
Class Popen(args,bufsize = 0,executable=None,
stdin =None,stdout =None,stderr =None,
preexec_fn = None,close_fds = False,shell = False,
cwd = None,env = None,universal_newlines = False,
startupinfo = None,creationflags = 0):
参数是:
args 应该是一个字符串,或一系列程序参数。要执行的程序通常是args序列或字符串中的第一项,但可以使用可执行参数进行显式设置。
在UNIX上,与shell=False(默认):在这种情况下,POPEN 类使用os.execvp()来执行子程序。 args通常应该是一个序列。一个字符串将被视为一个字符串作为唯一项目(要执行的程序)的序列。
在UNIX上,使用shell = True:如果args是一个字符串,则它指定要通过shell执行的命令字符串。如果args是一个序列,则第一个项目指定命令字符串,并且任何其他项目将被视为附加的shell参数。
可以先创建一个简单的shell脚本 a.sh
$1 $2 分别代表传进脚本的 第一个和第二个参数
如果不写shell=True,默认为shell=False,需要在args的第一个参数指定执行器路径
stdin,stdout和stderr分别指定执行的程序的标准输入,标准输出和标准错误文件句柄。有效值是PIPE,现有文件描述符(正整数),现有文件对象和 None。 PIPE表示应该创建一个新的管道给孩子。随着无,则不会发生重定向; 孩子的文件句柄将从父类继承。另外,stderr 可以是STDOUT,它表示应用程序的stderr数据应该被捕获到与stdout相同的文件句柄中。
在Popen对象中,可以设值subprocess.stdout=PIPE 即通过管道 p.stdout.read()取出 该进程的标准输出
preexec_fn 如果将preexec_fn设置为可调用对象,则该对象将在子进程执行前被调用。
如果close_fds为true,则在执行子进程之前,将关闭除0,1和2之外的所有文件描述符。
如果shell为true,则指定的命令将通过shell执行。
如果cwd不是None,那么在执行子代之前,当前目录将更改为cwd。
如果env不是None,它将为新进程定义环境变量。
如果设置universal_newlines为true,则文件对象stdout和stderr将作为文本文件打开,但可能会有\ n,Unix行尾约定\ r,Macintosh约定或\ r \ n中的任何行终止, Windows约定。所有这些外部表示被Python程序视为\ n。注意:此功能仅在Python是使用通用换行支持(默认)构建时才可用。此外,文件对象stdout,stdin和stderr的newlines属性不会被communications()方法更新。
如果设置了STARTUPINFO和creationflags,将被传递到下层的CreateProcess()函数。他们可以指定诸如主窗口的外观和新过程的优先级等内容。(仅限Windows)
Popen对象的一些方法
Popen.poll() 检查子进程是否终止,返回对象的returncode
Popen.wait() 等待子进程完成,阻塞。返回returncode
Popen.communicate(input=None) 将信息输入到进程,从stdout和stderr中读取数据,直到达到文件结尾。等待进程终止。可选的stdin参数应该是要发送到子进程的字符串,如果没有数据应发送给子进程,则为None。
返回一个元组(stdout,stderr) 但是读取的数据缓存在内存中,所以如果数据量很大或者无限,就不要使用这种方法
Popen.pid 返回子进程的pid
Popen.returncode 读取进程的状态码 None —— 子进程尚未结束;
==0 —— 子进程正常退出;
> 0—— 子进程异常退出,returncode对应于出错码;
< 0—— 子进程被信号杀掉了。
Popen.kill() 杀死进程