自定义使用subprocess执行SHELL命令的函数

封装一个使用subprocess的Popen执行SHELL命令的函数, 支持超时判断,支持读取stdout和stderr

# !/usr/bin/python
# -*- coding: UTF-8 -*-
# @author:zz
import shlex
import datetime
import subprocess
import time
import os


code_dct = {
    0: '执行成功',
    7: '找不到表',
    41: '查询字段不存在',
    64: '表示缺失关键字',
    127: '语句为空串'
}


def return_code_mean(code):
    if code in code_dct.keys():
        return code_dct[code]
    else:
        return "查询不到该返回状态值"


def execute_command(cmdstring, cwd=None, timeout=1200, shell=True):
    """执行一个SHELL命令
            封装了subprocess的Popen方法, 支持超时判断,支持读取stdout和stderr
            参数:
        cwd: 运行命令时更改路径,如果被设定,子进程会直接先更改当前路径到cwd
        timeout: 超时时间,秒,支持小数,精度0.1秒
        shell: 是否通过shell运行
    Returns: return_code
    Raises:  Exception: 执行超时
    """
    if shell:
        cmdstring_list = cmdstring
    else:
        cmdstring_list = shlex.split(cmdstring)
    if timeout:
        end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)

    print("> > > > > > >  In execute_command() ... ")
    print("comand: " + cmdstring)
    # 没有指定标准输出和错误输出的管道,因此会打印到屏幕上;
    sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE, shell=shell,stdout=subprocess.PIPE,stderr=subprocess.PIPE, bufsize=4096)

    # subprocess.poll()方法:检查子进程是否结束了,如果结束了,设定并返回码,放在subprocess.returncode变量中
    err_info = ""
    err_info_tmp = ""
    while sub.poll() is None:
        time.sleep(0.001)
        err_info_line = sub.stderr.readline().decode()
        if err_info_line:
            err_info += err_info_line
            print(err_info_line)
        if timeout:
            if end_time <= datetime.datetime.now():
                if err_info_tmp == err_info:
                    print('Errror shell 执行超时')
                    break
                else:
                    err_info_tmp = err_info
                    end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)

    if sub.returncode != 0:
        print("error")

    return sub.stdout.read().decode(), sub.returncode, err_info


if __name__ == '__main__':
    print(execute_command('ls -l'))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值