`

Python:封装允许执行命令有超时的类

 
阅读更多

封装允许执行命令有超时的类

#!/usr/bin/env python
import os;
import sys;
import time;
import fcntl;
import select;
import signal;
import commands;
import subprocess;

class CRunCmd:
    def __init__(self):
        pass;

    def __AsyncRecv(self, fdSock, nMaxRead = 1024 * 8):
        if not fdSock or fdSock.closed:
            return (False, '')

        #set fd non-block
        nFlags = fcntl.fcntl(fdSock, fcntl.F_GETFL);
        fcntl.fcntl(fdSock, fcntl.F_SETFL, nFlags | os.O_NONBLOCK)

        bRet = False
        strRead = ''
        try:
            #check can be read
            if not select.select([fdSock], [], [], 0)[0]:
                return (True, '')

            strRead = fdSock.read(nMaxRead);
            #if read empty, then close it
            if len(strRead) <= 0:
                fdSock.close();

            bRet = True;
        except:
            bRet = False;

        #reset fd
        if not fdSock.closed:
            fcntl.fcntl(fdSock, fcntl.F_SETFL, nFlags)

        return (bRet, strRead)

    def Run(self, lsCmd, nTimeOut = 0, nIntervalTime = 1):
        oProc = subprocess.Popen(lsCmd, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        strOut = ''
        strErr = '';

        nStartTime = time.time()
        while True:
            print(oProc.poll());
            if None != oProc.poll():
                break;

            #sleep nIntervalTime
            time.sleep(nIntervalTime)
            bRet, strBuf1 = self.__AsyncRecv(oProc.stdout);
            bRet, strBuf2 = self.__AsyncRecv(oProc.stderr);
            if len(strBuf1) > 0:
                strOut += strBuf1;
            if len(strBuf2) > 0:
                strErr += strBuf2;

            if (nTimeOut > 0) and (time.time() - nStartTime) > nTimeOut:
                print("time out...");
                break;

        #get last buff
        bRet, strBuf1 = self.__AsyncRecv(oProc.stdout);
        bRet, strBuf2 = self.__AsyncRecv(oProc.stderr);
        if len(strBuf1) > 0:
            strOut += strBuf1;
        if len(strBuf2) > 0:
            strErr += strBuf2;

        #if not finish, so timeout
        if None == oProc.poll():
            self.KillAll(oProc.pid)

        return (oProc.returncode, strOut, strErr)

    def KillAll(self, nKillPid, nKillSignal = signal.SIGKILL):
        print("kill pid:%s" %nKillPid)
        nRet, strOutput = commands.getstatusoutput('ps -A -o pid,ppid');
        if 0 != nRet:
            return (False, strOutput);

        mapPid = {};
        #make all ppid & pid map
        for strLine in strOutput.split('\n'):
            lsPid = strLine.strip().split();
            if 2 != len(lsPid):
                continue;

            strPid = lsPid[0];
            strPPid = lsPid[1];
            if strPPid in mapPid.keys():
                mapPid[strPPid].append(strPid);
            else:
                mapPid[strPPid] = [strPid];

        #get all kill pid list
        lsAllKillPid = [str(nKillPid)];
        lsToKillPid = [str(nKillPid)];
        while True:
            if len(lsToKillPid) <= 0:
                break;
            lsChild = []
            for strPid in lsToKillPid:
                if strPid in mapPid.keys():
                    lsAllKillPid.extend(mapPid[strPid]);
                    lsChild.extend(mapPid[strPid]);
                    print("[%s]append:%s" %(strPid, mapPid[strPid]));

            lsToKillPid = lsChild;
        print("kill pid list\n%s" %lsAllKillPid)
        #kill all process
        for strPid in reversed(lsAllKillPid):
            try:
                print("kill %s" %(strPid))
                #os.kill(int(strPid), nKillSignal)
            except:
                pass

        return (True, '')

 

/tmp/a.py

#!/usr/bin/env python
import time;
import os;
import sys;

def Fork():
    os.fork();
    print("pid:%s" %os.getpid());


if '__main__' == __name__:
    for i in xrange(0, int(sys.argv[1])):
        print("[%s] befor fork" %os.getpid());
        Fork();
        print("[%s] after fork" %os.getpid());
        time.sleep(1);

    print("[%s] start sleep" %os.getpid());
    time.sleep(10);
    print("[%s] end of process..." %os.getpid());

 


#test code

if "__main__" == __name__:
    oCmd = CRunCmd();
    nRet, strOut, strErr = oCmd.Run(['python', '/tmp/a.py', '10'], 5)
    print("ret:%s" %nRet);
    print("stdout:%s" %strOut);
    print("stderr:%s" %strErr);

 



执行结果:

$python w_p.py
None
None
None
None
None
time out...
kill pid:29443
[29443]append:['29444', '29446', '29450', '29457', '29474']
[29444]append:['29445', '29448', '29454', '29463']
[29446]append:['29449', '29456', '29465']
[29450]append:['29458', '29471']
[29457]append:['29473']
[29445]append:['29447', '29452', '29462']
[29448]append:['29453', '29461']
[29454]append:['29470']
[29449]append:['29455', '29468']
[29456]append:['29467']
[29458]append:['29472']
[29447]append:['29451', '29466']
[29452]append:['29459']
[29453]append:['29460']
[29455]append:['29469']
[29451]append:['29464']
kill pid list
['29443', '29444', '29446', '29450', '29457', '29474', '29445', '29448', '29454', '29463', '29449', '29456', '29465', '29458', '29471', '29473', '29447', '29452', '29462', '29453', '29461', '29470', '29455', '29468', '29467', '29472', '29451', '29466', '29459', '29460', '29469', '29464']
kill 29464
kill 29469
kill 29460
kill 29459
kill 29466
kill 29451
kill 29472
kill 29467
kill 29468
kill 29455
kill 29470
kill 29461
kill 29453
kill 29462
kill 29452
kill 29447
kill 29473
kill 29471
kill 29458
kill 29465
kill 29456
kill 29449
kill 29463
kill 29454
kill 29448
kill 29445
kill 29474
kill 29457
kill 29450
kill 29446
kill 29444
kill 29443
ret:None
stdout:
stderr:

分享到:
评论

相关推荐

    mysql 数据库封装类

    - **批处理(Batch Processing)**:允许一次性发送多个SQL语句,减少网络通信次数,提高执行效率。 3. **事务处理**: 封装类提供事务开始、提交、回滚的方法,确保数据的一致性。例如,`startTransaction()`、`...

    Python内置库:threading(多线程操作).docx

    可选的`timeout`参数允许在超时后恢复执行。 - `start()`: 开始线程的执行。 - `name`: 线程的名字,方便识别和调试。 **4. 线程安全与同步问题** 在多线程环境中,多个线程可能同时访问共享资源,可能导致数据不...

    python对于requests的封装方法详解

    封装后的`Requests`类继承自`object`,包含一个`requests.Session`实例以及相关的配置项,如超时时间、重试次数等。此外,还定义了一些用于存储响应结果的数据结构,例如`responses`字典用于保存每个请求的响应数据...

    Python实现ping命令

    在Python中,我们需要构建这个报文,并将其封装到UDP数据包中。 3. **套接字编程**:创建套接字,设置超时,绑定本地端口(虽然ICMP协议通常不需要,但为了完整起见),然后向目标IP地址发送数据。同时,需要开启一...

    python中执行shell的两种方法总结

    例如,`commands.getstatusoutput(cmd_String)`函数会执行给定的Shell命令`cmd_String`,并返回一个包含命令执行状态和输出结果的元组。状态通常是退出代码,而输出是命令的标准输出。然而,需要注意的是,`commands...

    爱心源码 python的mysql数据池封装

    本资源"爱心源码 - Python的MySQL数据池封装"提供了一种优化的解决方案,帮助开发者更高效、稳定地执行数据库操作。数据池(Connection Pool)是一种管理数据库连接的机制,它允许多个并发请求共享有限数量的数据库...

    一个封装良好的SOCKET通信类

    8. **日志记录**:为了方便调试和问题追踪,类可能有日志记录功能,记录连接、发送、接收等关键操作的信息。 9. **易于使用**:为了提高开发效率,类的设计应该遵循面向对象的原则,提供清晰的API文档,使开发者...

    Python-redis

    `redis`库还提供了其他高级特性,如lua脚本执行、超时设置、持久化操作等。例如,你可以使用`eval`或`evalsha`方法执行lua脚本,提高操作效率。 总的来说,Python的`redis`库提供了丰富的API,能够满足各种Redis...

    Python实现基于小红书 Web 端进行的请求封装项目源码

    该项目是使用Python编程语言对小红书Web端的网络请求进行封装的一个实例,旨在提供一个高效、便捷的方式来处理与小红书平台相关的API交互。在Python中,通常使用requests库来执行HTTP请求,而本项目可能就是基于此库...

    PyPI 官网下载 | python-subprocess-utils-0.0.1.tar.gz

    1. **命令封装**:将复杂的命令行参数包装成易于理解和使用的Python对象,使得调用外部程序变得更加直观。 2. **结果处理**:提供统一的接口来获取子进程的输出、错误信息和返回码,使得错误处理更加简单。 3. **...

    自动测试python文档

    2. 页面对象模式:这是一种最佳实践,用于组织和抽象测试代码,将页面元素和它们的操作封装为单独的类。这样可以提高代码的可维护性和可重用性。 3. 查找元素:Selenium提供了多种方法来定位页面上的元素,如通过ID...

    基于Python的GBN协议实现

    在实际操作中,你需要为这两个类添加具体的实现细节,包括数据包的封装与解封、超时重传逻辑、错误检测和纠正功能等。通过这样的实践,你可以深入理解GBN协议的工作原理,并锻炼编程技能。 在学习这个过程时,一定...

    python2 poster 模块

    3. **执行构建与安装命令**:进入解压后的poster目录,使用命令行执行以下两行命令: - `python setup.py build`:这一步会编译源代码,生成Python可以理解的字节码文件。 - `python setup.py install`:这一步会...

    cmd_timeout:使用超时运行外部命令的实用程序

    总结来说,“cmd_timeout”是一个实用的Python工具,它扩展了`subprocess`模块的功能,为外部命令执行添加了超时控制。通过理解和使用“cmd_timeout”,我们可以使Python程序更加健壮,避免因长时间运行的命令导致的...

    python+接口自动化 demo

    我们可以使用类和方法封装测试逻辑,每个方法对应一个测试用例。 在压缩包“python-api-test接口自动化demo”中,你将找到使用以上知识点编写的示例代码,通过学习和实践,你可以快速掌握Python接口自动化测试的...

    基于python的接口自动化测试框架说明1

    **基于Python的接口自动化测试框架说明** 随着软件开发过程中接口数量的增加,手动测试接口的效率变得低下且易出错。为了解决这个问题,我们开发了一个轻量级的Python接口自动化测试框架,名为FreeTestGo,它能有效...

    Python-Python实现的轮询和回调API包

    本项目“Python-Python实现的轮询和回调API包”提供了一个专门的Python包,旨在简化这类任务的实现,减少代码冗余,提高代码可读性和可维护性。 轮询是一种重复检查状态或条件直到满足特定条件的机制。在API调用中...

    PyPI 官网下载 | executor-21.1.tar.gz

    5. **配置与自定义**:可能包含配置选项,允许开发者调整命令执行的行为,比如超时设置、命令的环境变量等。 6. **安全性**:executor库通常会处理一些潜在的安全风险,例如防止命令注入攻击,确保命令参数的正确...

    nyt_api_python:从《纽约时报》的API中提取文章数据

    3. **Python库集成**:`nyt_api_python`可能封装了一些与API交互的函数,简化了请求和解析响应的过程。通常,你需要导入这个库,然后使用其提供的方法来执行请求。 4. **请求构建**:根据API要求,构造合适的HTTP...

Global site tag (gtag.js) - Google Analytics