# -*- coding: utf-8 -*- ######################################################### import os, traceback, subprocess, json from framework import frame class ToolSubprocess(object): @classmethod def execute_command_return(cls, command, format=None, force_log=False, shell=False, env=None): try: #logger.debug('execute_command_return : %s', ' '.join(command)) if frame.config['running_type'] == 'windows': tmp = [] if type(command) == type([]): for x in command: if x.find(' ') == -1: tmp.append(x) else: tmp.append(f'"{x}"') command = ' '.join(tmp) iter_arg = '' process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=shell, env=env, encoding='utf8') #process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=shell, env=env, encoding='utf8') ret = [] with process.stdout: for line in iter(process.stdout.readline, iter_arg): ret.append(line.strip()) if force_log: logger.debug(ret[-1]) process.wait() # wait for the subprocess to exit if format is None: ret2 = '\n'.join(ret) elif format == 'json': try: index = 0 for idx, tmp in enumerate(ret): #logger.debug(tmp) if tmp.startswith('{') or tmp.startswith('['): index = idx break ret2 = json.loads(''.join(ret[index:])) except: ret2 = None return ret2 except Exception as exception: logger.error('Exception:%s', exception) logger.error(traceback.format_exc()) logger.error('command : %s', command) # 2021-10-25 # timeout 적용 @classmethod def execute_command_return2(cls, command, format=None, force_log=False, shell=False, env=None, timeout=None, uid=0, gid=0, pid_dict=None): def demote(user_uid, user_gid): def result(): os.setgid(user_gid) os.setuid(user_uid) return result try: if app.config['config']['running_type'] == 'windows': tmp = [] if type(command) == type([]): for x in command: if x.find(' ') == -1: tmp.append(x) else: tmp.append(f'"{x}"') command = ' '.join(tmp) iter_arg = b'' if app.config['config']['is_py2'] else '' if app.config['config']['running_type'] == 'windows': process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=shell, env=env, encoding='utf8') else: process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, shell=shell, env=env, preexec_fn=demote(uid, gid), encoding='utf8') new_ret = {'status':'finish', 'log':None} try: process_ret = process.wait(timeout=timeout) # wait for the subprocess to exit except: import psutil process = psutil.Process(process.pid) for proc in process.children(recursive=True): proc.kill() process.kill() new_ret['status'] = "timeout" ret = [] with process.stdout: for line in iter(process.stdout.readline, iter_arg): ret.append(line.strip()) if force_log: logger.debug(ret[-1]) if format is None: ret2 = '\n'.join(ret) elif format == 'json': try: index = 0 for idx, tmp in enumerate(ret): #logger.debug(tmp) if tmp.startswith('{') or tmp.startswith('['): index = idx break ret2 = json.loads(''.join(ret[index:])) except: ret2 = None new_ret['log'] = ret2 return new_ret except Exception as exception: logger.error('Exception:%s', exception) logger.error(traceback.format_exc()) logger.error('command : %s', command)