Python subprocess.call没有等待进程完成blender

时间:2017-04-11 23:52:51

标签: python shell subprocess blender git-bash

我在blender中有一个python脚本,它有

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脚本在MacOS上运行良好(在更改路径后)并在使用subprocess.call(['sh', '/userA/Test/run-my-script.sh'])时等待

但在Windows上发生这种情况,我在Blender中运行下面的python脚本然后一旦到达子进程行Git bash就打开并运行shell脚本,而blender没有等待它完成它只需在其控制台中打印Hello,而无需等待Git Bash完成。有什么帮助吗?

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

7 个答案:

答案 0 :(得分:5)

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

  

subprocess。 call args,*,stdin = None,stdout = None,stderr = None,shell = False,timeout = None

     

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

编辑:我想我对正在发生的事情抱有预感。该命令适用于你的Mac,因为Macs,我相信,开箱即用支持Bash(至少功能上等同于),而在Windows上,它会看到你试图运行“.sh”文件而是触发Git Bash,我认为在开始时会执行一些分叉。

由于这个Python 认为你的脚本已经完成,PID就消失了。

如果我是你,我会这样做:

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

希望这是有道理的。

答案 1 :(得分:4)

您可以使用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)

与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。

答案 2 :(得分:2)

默认情况下,

subprocess.run将等待该过程完成。

答案 3 :(得分:2)

使用 subprocess.Popen Popen.wait

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

您也可以使用check_call()代替Popen。

答案 4 :(得分:1)

您可以使用os.system,如下所示:

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

答案 5 :(得分:0)

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

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)

答案 6 :(得分:0)

一个疯狂的尝试,但是您是以管理员身份运行Shell还是以Blender以普通用户身份运行?

长话短说(很短),Windows UAC是管理员和普通用户之间的一种隔离环境,因此可能会发生类似这样的随机怪癖。不幸的是,我不记得它的来源,我发现最接近的是this

我的问题与您的正好相反,wait()陷入了无限循环,因为我的python REPL是从admin shell启动的,无法读取常规用户子进程的状态。恢复为普通用户外壳程序已修复。这不是我第一次受此UAC攻击。