【问题标题】:Python popen command. Wait until the command is finishedPython 弹出命令。等到命令完成
【发布时间】:2011-02-19 16:49:59
【问题描述】:

我有一个脚本,我可以在其中使用 popen 一个 shell 命令启动。 问题是脚本不会等到 popen 命令完成并立即继续执行。

om_points = os.popen(command, "w")
.....

如何告诉我的 Python 脚本等到 shell 命令完成?

【问题讨论】:

    标签: python subprocess wait popen


    【解决方案1】:

    根据您希望如何处理脚本,您有两种选择。如果您希望命令在执行时阻止而不做任何事情,您可以使用subprocess.call

    #start and block until done
    subprocess.call([data["om_points"], ">", diz['d']+"/points.xml"])
    

    如果你想在它正在执行的时候做一些事情或者把事情输入stdin,你可以在popen调用之后使用communicate

    #start and process things, then wait
    p = subprocess.Popen([data["om_points"], ">", diz['d']+"/points.xml"])
    print "Happens while running"
    p.communicate() #now wait plus that you can send commands to process
    

    如文档中所述,wait 可能会死锁,因此建议进行交流。

    【讨论】:

    • 查看subprocess.call上的文档
    • 虽然子进程在许多答案中是首选,但它不能很好地处理命令中的空间和配额。上面的答案并没有直接解决os.popen的问题。
    • 子进程可以比 os 系统慢 2 倍 - bugs.python.org/issue37790
    • subprocess.run() 是在 Python 3.5 中添加的,是“调用子进程的推荐方法”
    【解决方案2】:

    您可以使用subprocess 来实现此目的。

    import subprocess
    
    #This command could have multiple commands separated by a new line \n
    some_command = "export PATH=$PATH://server.sample.mo/app/bin \n customupload abc.txt"
    
    p = subprocess.Popen(some_command, stdout=subprocess.PIPE, shell=True)
    
    (output, err) = p.communicate()  
    
    #This makes the wait possible
    p_status = p.wait()
    
    #This will give you the output of the command being executed
    print "Command output: " + output
    

    【讨论】:

    • 子进程可以比 os 系统慢 2 倍 - bugs.python.org/issue37790
    【解决方案3】:

    强制popen 在通过以下操作读取所有输出之前不要继续:

    os.popen(command).read()
    

    【讨论】:

    • 我不是 python 专家,但这似乎是对原始代码进行最少修改的最简单的解决方案。为什么这不是一个好的解决方案?
    • @jdmcnair 我的猜测是,如果命令抛出错误,这个 .read() 方法会破坏父进程。但是其他一些方法将子进程中的错误与影响父进程分离。我猜如果子进程永远挂起, .read() 将永远等待结果。
    【解决方案4】:

    让你试图传递的命令是

    os.system('x')
    

    然后你把它转换成一个声明

    t = os.system('x')
    

    现在,python 将等待命令行的输出,以便将其分配给变量 t

    【讨论】:

      【解决方案5】:

      您正在寻找的是wait 方法。

      【讨论】:

      • 但是如果我输入: om_points = os.popen(data["om_points"]+" > "+diz['d']+"/points.xml", "w").wait () 我收到这个错误: Traceback (last recent call last): File "./model_job.py", line 77, in om_points = os.popen(data["om_points"]+" > "+diz[ 'd']+"/points.xml", "w").wait() AttributeError: 'file' object has no attribute 'wait' 有什么问题?再次感谢。
      • 您没有点击我提供的链接。 waitsubprocess 类的一个方法。
      • 如果进程写入标准输出而没有人读取它,等待会死锁
      • 子进程可以比 os 系统慢 2 倍 - bugs.python.org/issue37790
      【解决方案6】:

      wait() 对我来说很好用。子进程 p1、p2 和 p3 同时执行。因此,所有过程都在 3 秒后完成。

      import subprocess
      
      processes = []
      
      p1 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
      p2 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
      p3 = subprocess.Popen("sleep 3", stdout=subprocess.PIPE, shell=True)
      
      processes.append(p1)
      processes.append(p2)
      processes.append(p3)
      
      for p in processes:
          if p.wait() != 0:
              print("There was an error")
      
      print("all processed finished")
      

      【讨论】:

      • 子进程可以比 os 系统慢 2 倍 - bugs.python.org/issue37790
      【解决方案7】:

      我认为 process.communicate() 适合小尺寸的输出。对于更大的输出,这不是最好的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-20
        • 2012-07-19
        • 2019-02-03
        • 2021-06-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多