本文参考https://mp.weixin.qq.com/s/2XQKrKAUr54ER4SHwRYciQ,单纯为了学习理解

作为胶水语言,Python可以很方便的执行系统命令,Python3中常用的执行操作系统命令有os.system()、os.popen()、subprocess.popen()、subprocess.call()、subprocess.run()、subprocess.getstatusoutput()六种方法。 也就是说依赖于os和subprocess库,可以实现对linux系统命令的操作,并分别有两种和四种实现方法。下面依次查看.

1、os.system

system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程。

其返回值是指令运行后返回的状态码,0表示指令成功执行,1表示失败,256表示没有返回结果,该方法适用于系统命令不需要输出内容的场景。

用法:

os.system("command")

示例:

import os
a=os.system("lsb_release -a")#用a接收返回值

在这里插入图片描述
当然还有其它类似命令:

import os
os.system("ls")
os.system("cd test && mkdir test1")

总之,可以在os.system中执行shell中通常可以执行的命令。

2、os.popen(command,mode)

这种调用方式是通过管道的方式来实现,这个函数的返回值是一个文件对象,可以读或者写(由mode决定,mode默认是’r’)。如果mode为’r’,调用该对象的read()或readlines()方法可以读取输出内容。

用法:

os.popen(command[, mode[, bufsize]])

os.system(cmd)或os.popen(cmd),前者返回值是脚本的退出状态码,后者的返回值是脚本执行过程中的输出内容。

a = os.popen("lsb_release -a")
print(a.read())
a= os.popen("ifconfig")
print(a.read())

在这里插入图片描述

3、subprocess模块

subprocess模块是python从2.4版本开始引入的模块,主要用来取代 一些旧的模块方法,如os.system、os.spawn、os.popen、commands.*等。官方推荐使用该模块执行系统命令,subprocess模块通过子进程来执行外部指令,并通过input/output/error管道,获取子进程的执行的返回信息。

好处在于:运用对线程的控制和监控,将返回的结果赋于一变量,便于程序的处理。

3.1 subprocess.Popen()

使用Popen可以创建进程,并与进程进行复杂的交互。
用法:

child = subprocess.Popen(["cmd","arg1"...])

常用参数说明:
在这里插入图片描述
示例:

from subprocess import PIPE,Popen
#返回的是Popen实例对像
proc = Popen(
    'lsb_release -a',  # cmd特定的查询空间的命令
    stdin=None,  # 标准输入 键盘
    stdout=PIPE,  # -1 标准输出(演示器、终端) 保存到管道中以便进行操作
    stderr=PIPE,  # 标准错误,保存到管道
    shell=True)
# print(proc.communicate()) # 标准输出的字符串+标准错误的字符串
outinfo, errinfo = proc.communicate()
print(outinfo.decode('gbk'))  # 外部程序(windows系统)决定编码格式
print(errinfo.decode('gbk'))
print(outinfo.decode('utf-8'))  # 外部程序(linux系统)决定编码格式
print(errinfo.decode('utf-8'))

在这里插入图片描述

3.2 subprocess.call()

执行指定的命令, 返回命令执行状态, 功能类似os.system(cmd),参数shell默认为False
用法:

subprocess.call("command")

示例:

import subprocess
subprocess.call(["lsb_release","-a"])# 数组作为参数运行命令

在这里插入图片描述

3.3 subporcess.run()

python3.5中新增的函数, 执行指定的命令, 等待命令执行完成后返回一个包含执行结果的CompletedProcess类的实例。run默认不会返回输出,只返回命令和执行状态。

用法:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, shell=False, timeout=None, check=False, universal_newlines=False)

示例:

import subprocess
completed = subprocess.run(["lsb_release","-a"])
print('returncode:',completed.returncode)

在这里插入图片描述

3.4 subprocess.getstatusoutput()

执行cmd命令,返回一个元组(命令执行状态,命令执行结果输出)。

返回状态码和结果,0表示成功

示例:

import subprocess
ret, val = subprocess.getstatusoutput("lsb_release -a")
print(ret)
print(val)

在这里插入图片描述

4.实际用例

用python为开启的服务写一个守护进程。
定义一个每隔5秒就输出当前时间的python程序time.py

import time
while True:
    #输出年月日时分秒
    print(time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(time.time())))
    time.sleep(5)

运行结果为:
在这里插入图片描述
此时,要写一个守护程序来检查这个时间程序是否在运行,如果没有要重新启动。具体会用到linux的ps命令:

ps aux | grep time.py |grep -v grep

在这里插入图片描述
所以用python来做就要执行shell命令:
可以这样,定义check.py:
用os.popen

import os
import time

def execCmd(cmd):
    r = os.popen(cmd)
    text = r.read()
    r.close()
    return text
while True:
    #检查程序是否在运行
    programIsRunningCmd = "ps -aux | grep time.py | grep -v grep"
    programIsRunningCmdAns = execCmd(programIsRunningCmd)
    #打印返回结果
    print(programIsRunningCmdAns)
    ansLine = programIsRunningCmdAns.split(' ')
    print(ansLine)

    # 判断打印结果
    if len(ansLine) > 2:
        print(time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(time.time()))+"  time.py is running")
        #休息20秒,除低检查频率
        time.sleep(20)
    else:
        print("restarting time.py")
        os.system('nohup python time.py > time.log 2>&1 &')
        #0 表示stdin标准输入
        #1 表示stdout标准输出
        #2 表示stderr标准错误

check.py也要后台进行运行:

nohup python check.py > /dev/null 2>&1 &

/dev/null 表示输出空设备,不显示。
在这里插入图片描述
其它几个命令就不试了,按需进行深度研究吧。

实护程序如果换成shell脚本,check.sh:

while true;
do
        server=`ps -aux | grep time.py | grep -v grep`
        if [ ! "$server" ]; then
            #echo "time.py挂了" | ./start.sh     
            echo "time.py挂了,进行重启" 
            nohup python time.py > time.log 2>&1 &                      
            # break
        fi
        sleep 5
done

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐