我正在寻找一种跨平台的方式来运行命令,等待它执行,然后返回输出,错误消息(如果有的话)和返回代码
以下代码在Windows上正常运行
run(["start", "/wait", "msiexec", "/i", msi_file_name, "/q"])
但是同样的格式拒绝在Linux上运行,除非我像列表中的1个字符串项一样传递它
run(["rpm -i {}".format(rpm_file_name)])
在Mac OS上,问题更进一步,例如,如果我尝试检查代码符号
run(["codesign", "-dvv", binary_file_name])
它会返回包含帮助信息的错误,并且命令不会执行 并试图打电话
run(["codesign -dvv".format(binary_file_name)])
命令执行但输出在sd_err而不是std_out
我的代码是否存在一些缺陷,或者这是否与子进程模块有关?是否建议调用子进程模块方法,即选择call,check_output,具体取决于命令,而不是像我一样尝试统一的方法?
def run(command_to_run) -> tuple:
"""
Runs a command on the shell
:param command_to_run: The command to be run as a list or as a string
:return: tuple with standard output, standard error and return code
"""
command_as_str = " ".join(command_to_run) if isinstance(command_to_run, list) else command_to_run
try:
Logger.info("Running command {}".format(command_as_str))
# Please provide a mechanism to run this on Windows without passing shell=True
process = subprocess.Popen(command_to_run, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True, universal_newlines=True)
std_out, std_err = process.communicate()
std_out = std_out.strip()
std_err = std_err.strip()
return_code = process.returncode
Logger.info("Output: {}, Error:{}, Return Code:{}".format(std_out, std_err, return_code))
except Exception as excp:
Logger.error("Exception: {}, Arguments:{}".format(type(excp), excp.args))
std_out, std_err = (type(excp).__name__, ''.join(excp.args))
return_code = -1
return std_out, std_err, return_code