Python的subprocess.call不等待进程结束搅拌机

问题描述:

我有搅拌器Python脚本,其中有Python的subprocess.call不等待进程结束搅拌机

subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),shell=True)

其次是取决于这个shell脚本来完成许多其他的代码。会发生什么,它不会等待它完成,我不知道为什么?我甚至用Popen代替call试图如图所示:

p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),shell=True) 
p1.wait() 

,我尝试使用commuincate,但它仍然没有奏效:

p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),shell=True).communicate() 

这个shell脚本在Mac OS的伟大工程(转换路后)并在使用时等待subprocess.call(['sh', '/userA/Test/run-my-script.sh'])

但在Windows上这是发生了什么,我在Blender中运行下面的python脚本,然后一旦它进入子进程行Git bash打开并运行shell脚本,而搅拌机不等待它完成它只是在其控制台打印Hello而无需等待Git Bash完成。任何帮助?

import bpy 
import subprocess 
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),shell=True) 
print('Hello') 
+1

,当你运行'在Windows上会发生什么d:/测试/运行我的-script.sh'命令行?它是否立即返回? – AShelly

+0

你可以发布bash脚本吗? –

subprocess.run将默认等待进程结束。

+0

但我的情况下,它不会等待,这就是为什么我问... – Tak

+0

您的问题给了我你使用'subprocess.Popen'的inpression而不是'subprocess.run'它不等待使用运行? – Grr

+0

我使用了subprocess.run,但它并没有等待 – Tak

您可以使用subprocess.call来做到这一点。

子过程。 呼叫指定参数时,*,标准输入=无,标准输出=无,标准错误=无,壳=假,超时=无

运行由ARGS中描述的命令。等待命令完成,然后返回returncode属性。

编辑:我觉得我有什么事情预感。该命令适用于Mac,因为Mac相信支持Bash开箱即用(至少在功能上等同于),而在Windows上它看到您尝试运行“.sh”文件,而是激发了Git Bash,假设开始时执行一对分叉。

因为这个Python 认为你的脚本已经完成,所以PID不见了。

如果我是你,我会做到这一点:

  • 使用tempfile模块生成一个唯一的,不存在的,绝对在你的“启动”脚本路径。
  • 启动脚本时,请将您刚才创建的路径作为参数传递。
  • 当脚本启动时,让它在路径上创建一个文件。完成后,删除文件。
  • 启动脚本应监视该文件的创建和删除以指示脚本的状态。

希望这是有道理的。

+0

有些情况下,这不起作用。 以我为例,该过程是一个程序,它创建一个文件,然后访问该文件以修改其内容一段时间。当程序仍在修改文件的内容并且进程仍在进行时,子进程调用将该进程视为已完成,当文件被创建时。任何解决方法可用? – SeF

+0

@SeF然后,你正在做一些意想不到的事情 - 文档非常明确地说明了函数的工作原理。也许你正在分叉或执行到另一个进程? – joeb

您可以使用os.system,像这样:

import bpy 
import os 
os.system("sh "+os.path.abspath('D:/Test/run-my-script.sh')) 
print('Hello') 

使用subprocess.PopenPopen.wait

process = subprocess.Popen(['D:/Test/run-my-script.sh'],shell=True, executable="/bin/bash") 
process.wait() 

你也可以使用check_call()代替POPEN。

您可以使用Popen.communicate API。

p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),shell=True) 
sStdout, sStdErr = p1.communicate() 

命令

Popen.communicate(input=None, timeout=None) 

互动与过程:发送数据到标准输入。从stdout和stderr中读取数据,直到达到文件结尾。等待进程终止。

+0

感谢所有参与赏金的人士,这个答案提出了一个等待命令的替代方案,它似乎并不是一直都在工作。 – SeF

显然有运行命令失败的情况。 这是我的解决方法:

def check_has_finished(pfi, interval=1, timeout=100): 
    if os.path.exists(pfi): 
     if pfi.endswith('.nii.gz'): 
      mustend = time.time() + timeout 
      while time.time() < mustend: 
       try: 
        # Command is an ad hoc one to check if the process has finished. 
        subprocess.check_output('command {}'.format(pfi), shell=True) 
       except subprocess.CalledProcessError: 
        print "Caught CalledProcessError" 
       else: 
        return True 
       time.sleep(interval) 
      msg = 'command {0} not working after {1} tests. \n'.format(pfi, timeout) 
      raise IOError(msg) 
     else: 
      return True 
    else: 
     msg = '{} does not exist!'.format(pfi) 
     raise IOError(msg)