def run_command_win(cmd, work_dir, timeout, logger, env=None): """Run commands using subprocess on Windows""" new_env = add_run_path(str(work_dir)) new_env.update(env) process_command = subprocess.Popen( cmd, shell=True, cwd=str(work_dir), env=new_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) logger.debug("execute cmd ===>>>: %s", cmd) return_code = com_out = com_err = None try: com_out, com_err = process_command.communicate(timeout=timeout) except subprocess.CalledProcessError as err: return_code, com_out, com_err = err.returncode, "", err logger.exception(err) return return_code, com_out, com_err except subprocess.TimeoutExpired: return_code, com_out, com_err = 3, "TimeOut", "TimeOut" return return_code, com_out, com_err else: return_code = process_command.returncode com_out = com_out.decode(ENCODING, errors="replace") com_err = com_err.decode(ENCODING, errors="replace") return return_code, com_out, com_err finally: process_command.kill() logger.debug("return code: %d", return_code) logger.debug("stdout : \n%s", indent(com_out, "+\t", lambda line: True)) logger.debug("stderr : \n%s", indent(com_err, "@\t", lambda line: True))
def run_command_win(cmd, work_dir, timeout, logger, env=None): """Run commands using subprocess on Windows We set PYTHONIOENCODING to utf-8 on Windows to keep up with test case file`s read encoding in compare.py to avoid some character set issues. """ new_env = add_run_path(str(work_dir)) new_env.update(env) encoding_env = {'PYTHONIOENCODING': 'utf-8'} new_env.update(encoding_env) process_command = subprocess.Popen( cmd, shell=True, cwd=str(work_dir), env=new_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) logger.debug("execute cmd ===>>>: %s", cmd) return_code = com_out = com_err = None try: com_out, com_err = process_command.communicate(timeout=timeout) except subprocess.CalledProcessError as err: return_code, com_out, com_err = err.returncode, "", err logger.exception(err) return return_code, com_out, com_err except subprocess.TimeoutExpired: return_code, com_out, com_err = 3, "TimeOut", "TimeOut" return return_code, com_out, com_err else: return_code = process_command.returncode com_out, com_err = handle_result_encoding(com_out, com_err, logger) return return_code, com_out, com_err finally: handle = ctypes.windll.kernel32.OpenProcess(1, False, process_command.pid) ctypes.windll.kernel32.TerminateProcess(handle, -1) ctypes.windll.kernel32.CloseHandle(handle) logger.debug("return code: %d", return_code) logger.debug( "stdout : \n%s", indent(com_out, "+\t", lambda line: True).encode().decode(ENCODING, errors='ignore')) logger.debug( "stderr : \n%s", indent(com_err, "@\t", lambda line: True).encode().decode(ENCODING, errors='ignore'))
def run_command_linux(cmd, work_dir, timeout, logger, env=None): new_env = add_run_path(str(work_dir)) new_env.update(env) process_command = subprocess.Popen( cmd, shell=True, cwd=str(work_dir), env=new_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, start_new_session=True, ) logger.debug("execute cmd ===>>>: %s", cmd) return_code = com_out = com_err = None try: com_out, com_err = process_command.communicate(timeout=timeout) except subprocess.CalledProcessError as err: return_code, com_out, com_err = err.returncode, "", err logger.exception(err) return return_code, com_out, com_err except subprocess.TimeoutExpired: return_code, com_out, com_err = 3, "", "TimeOut" return return_code, com_out, com_err else: return_code = process_command.returncode com_out, com_err = handle_result_encoding(com_out, com_err, logger) return return_code, com_out, com_err finally: process_command.kill() try: os.killpg(process_command.pid, signal.SIGTERM) except ProcessLookupError: pass logger.debug("return code: %d", return_code) logger.debug( "stdout : \n%s", indent(com_out, "+\t", lambda line: True).encode().decode(ENCODING, errors='ignore')) logger.debug( "stderr : \n%s", indent(com_err, "@\t", lambda line: True).encode().decode(ENCODING, errors='ignore'))
def run(cmd, work_dir, timeout): process_command = subprocess.Popen( cmd, shell=True, cwd=str(work_dir), env=add_run_path(str(work_dir)), stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, ) try: com_out, com_err = process_command.communicate(timeout=timeout) except subprocess.CalledProcessError as err: raise err else: return_code = process_command.returncode com_out = com_out.decode(ENCODING, errors="ignore") com_err = com_err.decode(ENCODING, errors="ignore") return return_code, com_out, com_err finally: process_command.terminate()