关于 subprocess

https://www.jb51.net/article/210406.htm subprocess popen shell参数的作用 True or False

https://blog.csdn.net/dlnb526/article/details/122951970

使用自己的文件流输出日志

import subprocess
import traceback
import tempfile
try:
    cmd = "ls -lh"
    out_temp = tempfile.SpooledTemporaryFile(bufsize=10*1000)
    fileno = out_temp.fileno()
    obj = subprocess.Popen(cmd,stdout=fileno,stderr=fileno,shell=True)
    obj.wait()
    
    out_temp.seek(0)
    lines = out_temp.readlines()
    
    
    print lines
except Exception, e:
    print traceback.format_exc()
finally:
    if out_temp:
        out_temp.close()

# 其实随便用一个open创建的文件流也可以
# eg:上面的fileno可以改成这样
fileno = open(os.path.join(path_td, task_id + '.log'), 'w')

subproces 的多进程执行方法,就是挨个阻塞,然后等执行结束,核心是communicate()这个方法

                log_file = self.make_log(file, self.ipipeid_people_starttime)
                # 拼接命令传的list是字符串形式,直接用中括号会解析成正则报错
                python_cmd = python_exe + " " + ROOT_PATH + "process_select.py " + self.ipipeid_people_starttime + " " + self.num \
                    + " " + self.key + " '" + self.std_tag_list + "' '" + self.importance_list + "' " + file 
                print(python_cmd)
                # 0是拼接if_async =0 只执行取结果
                s = subprocess.Popen(python_cmd + " 0 " + self.task_id, stdout=log_file, stderr=log_file, shell=True)
                sleep_procs.append(s)
                # os.system(python_cmd) # 阻塞的,不用这个方案
            for proc in sleep_procs:
                proc.communicate() # 阻塞主进程到子进程执行结束
                p_code = proc.returncode
                _ecode_list.append(p_code) # 填充每个子进程的执行结果
                if p_code != 0:
                    task_status = -1 # 有一个子进程执行结果为非0则该任务task_status就置为-1

subprocess 好处是安全,但是不支持超时,所以这里取巧用了threading模块的定时器,这里超时就杀死了,同样可以自己定义超时报警等

import subprocess
from threading import Timer
 
def kill_command(p):
    """终止命令的函数"""
    p.kill()
 
def execute(command, timeout):
    # 执行shell命令
    p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
    # 设置定时器去终止这个命令
    timer = Timer(timeout, kill_command, [p])
 
    try:
        timer.start()
        stdout, stderr = p.communicate()
        return_code = p.returncode
        print(return_code)
        print(stdout)
        print(stdout)
    except Exception as ex:
        print(ex)
    finally:
        timer.cancel()

 

posted @ 2022-08-31 17:26  刘大胖  阅读(61)  评论(0)    收藏  举报