【问题标题】:Python's Subprocess.Popen With Shell=True. Wait till it is completedPython 的 Subprocess.Popen 与 Shell=True。等到完成
【发布时间】:2013-12-25 09:53:06
【问题描述】:

提交由完整文件路径组成的复杂 cmd 字符串到可执行文件,多个标志、参数、参数、输入和输出似乎需要我设置 shell=True 否则 subprocess.Popen 无法理解比简单的可执行路径更复杂的东西(文件路径中没有空格)。

在我的示例中,我有一个很长的 cmd:

cmd = " '/Application/MyApp.app/Contents/MacOS/my_executable' '/Path/to/input/files' -some -flags -here -could -be -a -lot '/full/path/to/output/files' "

将此 cmd 提交到 subprocess.Popen ”会导致错误,该错误抱怨有关路径的某些内容并且无法找到它。

所以不要使用:

proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

check_call 似乎运作良好:

proc = subprocess.check_call(cmd, shell=True)

有趣,只有在 shell 设置为 True

shell=True 

subprocess.check_call 与提供的 cmd 一起工作。

副作用是其余代码似乎继续运行而无需等待 subprocess.check_call(cmd, shell=True) 首先完成。

代码的设计方式是其余的执行取决于subprocess.check_call(cmd, shell=True) 的结果。

我想知道是否有强制执行代码等到 subprocess.check_call(cmd, shell=True) 完成。提前致谢!

【问题讨论】:

  • 您是否尝试在使用shell=Falsesubprocess.Popen 运行时将cmd 转换为列表?您可以使用shlex.split() 函数来执行此操作,就像documentation of the Popen constructor 中提供的示例代码一样。

标签: python subprocess popen


【解决方案1】:

正如@mikkas 建议的那样,只需将其用作list 这是一个工作示例:

mainProcess = subprocess.Popen(['python', pyfile, param1, param2], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# get the return value from the method
communicateRes = mainProcess.communicate()

stdOutValue, stdErrValue = communicateRes

你打电话给python.exe pyfile param1 param2

通过使用communicate(),您可以获得stdoutstderr 作为Tuple

您可以使用python方法split()将您的字符串拆分为一个列表,例如:

cmd = "python.exe myfile.py arg1 arg2"

cmd.split(" ")

输出:

['python.exe', 'myfile.py', 'arg1', 'arg2']

【讨论】:

  • 避免使用cmd.split(' '),因为它无法处理引号。改用shlex.split,它知道用于shell命令的语法,因此它可以按预期处理'program "a single argument with quotes"'之类的东西。
  • 很高兴不知道
【解决方案2】:

我认为 check_call 函数应该等待命令完成。

在此处查看文档 http://docs.python.org/2/library/subprocess.html

【讨论】:

  • 我需要读取正在运行的进程的标准输出。 subprocess.check_call 是否允许读取其标准输出?如果是这样,请您说明如何做到这一点。
  • 你为什么不尝试使用 subprocess.check_output 来代替?
【解决方案3】:

检查调用不等待。您需要执行 process.wait() 并明确检查返回代码以获得所需的功能。

Process = subprocess.Popen('%s' %command_string,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
            Process.wait()
            if Process1.returncode!=0:
                    print Process1.returncode
                    sendMail()
                    return
            else:
                    sendMail()

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2015-03-01
    • 2021-02-03
    • 2015-02-09
    • 2017-04-14
    • 1970-01-01
    相关资源
    最近更新 更多