【发布时间】:2020-07-20 17:30:09
【问题描述】:
在使用 subprocess.Popen 时遇到一些麻烦。
这是我正在使用的代码:
def parse_replay(rep_record):
rep_path = rep_record['rep_path']
screp_cmd = f"{cwd}/screp -cmds -mapres -maptiles '{rep_path.replace('..', os.path.dirname(cwd))}'"
p = subprocess.Popen(screp_cmd, shell=True)
out = p.stdout.read()
rep_action_log = json.loads(out)
return rep_action_log
如果我使用 shell=False,我会收到文件未找到错误。 使用 shell=True 时,命令被执行但函数没有返回(显然它一直在监听命令的输出)。
你知道有什么方法可以在正确完成我的函数执行的同时捕获我的命令的标准输出吗?
PS:screp 是一个将 json 信息输出到标准输出的 CLI https://github.com/icza/screp
【问题讨论】:
-
这看起来不像是一个您有充分理由使用
shell=True的命令,并且冒着随之而来的安全漏洞的风险。为什么不将您的参数列表作为列表传递,以便您可以使用shell=False? -
即:
screp_cmd = [ f"{cwd}/screp", "-cmds", "-mapres", "-maptiles", f"{rep_path.replace('..', os.path.dirname(cwd))}"] -
也就是说,能够捕获标准输出与
shell=True或shell=False无关。您无法捕获标准输出,因为您没有通过stdout=subprocess.PIPE。 -
...理想情况下,使用
subprocess.communicate(),同时明确设置stdin、stdout和stderr中的所有三个(如何设置取决于您希望在 stderr 上发生什么,以及您是否希望从 Python 进程本身继承 stdin)。 -
...无论如何,为了让任何人能够全面回答这个问题,他们需要了解更多关于
screp的信息——它从哪些文件描述符中读取、写入和写入的文件什么顺序。理想情况下,更好的minimal reproducible example 只需要人们已经拥有的工具,因此没有这个“screp”工具的人可以自己看到问题。
标签: python subprocess