欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python调用shell的几种姿势

程序员文章站 2022-07-07 19:57:32
...

大家都清楚,python是一门易上手、简单灵活的胶水语言,能与多种语言进行交互,易用、入门和上手都比较简单,所以一直都被广泛使用。

Python开发一些devops的自动化作业也是非常方便的,在Linux环境下,我们用shell编写自动化脚本,通常自动化作业复杂的话,使用shell脚本就很难搞定了,一方面,shell脚本量大了之后就会比较难以工程化,维护和阅读,另外shell是不具有编程语言丰富的类库,如map list在shell这里有版本影响。因此,这个时候python+shell两者相结合,直接交互取长补短,就非常适合开发各种自动化作业了。

Python与shell交互:

方式一:

使用os.system方法

import os

myCmd = 'ls'

os.system(myCmd)

在linux终端上,执行xxx.py脚本文件,即可

方式二:

使用os.popen方法

import os

myCmd = 'echo test123...'

stream = os.popen(myCmd)

output = stream.read()

print(output)

方式三:

Subprocess模块的出现是用来替代OS模块中的system()和popen()方法的。官方推荐只用subprocess模块执行系统命令,subprocess模块允许我们启动一个新的进程,并连接到它们的输入/输出/错误管道,从而获取返回值。

Popen是subprocess的核心,子进程的创建和管理都靠它处理

class subprocess.Popen(

args,

bufsize=-1,

executable=None,

stdin=None,

stdout=None,

stderr=None,

preexec_fn=None,

close_fds=True,

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)

参数介绍如下:

args:shell命令,可以是字符串或者序列类型(如:list,元组)

bufsize:缓冲区大小。当创建标准流的管道对象时使用,默认-1。0:不使用缓冲区 1:表示行缓冲,仅当universalnewlines=True时可用,也就是文本模式 正数:表示缓冲区大小 负数:表示使用系统默认的缓冲区大小。

stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄

preexecfn:只在 Unix 平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用

shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。

cwd:用于设置子进程的当前目录。

env:用于指定子进程的环境变量。如果 env = None,子进程的环境变量将从父进程中继承。

主要方法:

poll(): 检查进程是否终止,如果终止返回 returncode,否则返回 None。

wait(timeout): 等待子进程终止。

communicate(input,timeout): 和子进程交互,发送和读取数据。

send_signal(singnal): 发送信号到子进程 。

terminate(): 停止子进程,也就是发送SIGTERM信号到子进程。

kill(): 杀死子进程。发送 SIGKILL 信号到子进程。

#用Python实时过滤xx.log日志文件,如同bash的tail -F xx.log

import subprocess



def run(filename):

    f = subprocess.Popen(['tail','-F',filename],stdout=subprocess.PIPE,stderr=subprocess.PIPE)

    while True:

        line = f.stdout.readline()

        print(line)



if __name__ == '__main__':

    filename = 'test0713.log'

    #filename = sys.argv[1]

    run(filename)