Python subprocess.call不等待进程完成搅拌机
我在blender中有一个python脚本Python subprocess.call不等待进程完成搅拌机,python,shell,subprocess,blender,git-bash,Python,Shell,Subprocess,Blender,Git Bash,我在blender中有一个python脚本 subprocess.call(os.path.abspath('D:/Test/runmyscript.sh'),shell=True) 接下来是许多依赖于此shell脚本完成的其他代码。发生的事情是,它不等待它完成,我不知道为什么?我甚至尝试使用Popen而不是call,如图所示: p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),shell=True) p1.wai
subprocess.call(os.path.abspath('D:/Test/runmyscript.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')
subprocess.run默认情况下将等待进程完成 您可以使用子流程。调用
来实现这一点
子进程。调用(args,*,stdin=None,stdout=None,stderr=None,shell=False,timeout=None)
运行args描述的命令。等待命令完成,然后返回returncode属性
编辑:我想我对正在发生的事情有预感。这个命令可以在Mac上运行,因为我相信Mac支持开箱即用的Bash(至少在功能上是等效的),而在Windows上,它看到您试图运行一个“.sh”文件,而启动Git Bash,我认为它在启动时会执行一些分叉
因为Python认为您的脚本已经完成,PID就消失了
如果我是你,我会这样做:
- 使用模块在“启动”脚本中生成唯一的、不存在的绝对路径
- 启动脚本时,将刚刚创建的路径作为参数传递
- 当脚本启动时,让它在路径处创建一个文件。完成后,删除该文件
- 启动脚本应监视该文件的创建和删除,以指示脚本的状态李>
希望这是有意义的。您可以使用os.system
,如下所示:
import bpy
import os
os.system("sh "+os.path.abspath('D:/Test/run-my-script.sh'))
print('Hello')
使用和:
process = subprocess.Popen(['D:/Test/run-my-script.sh'],shell=True, executable="/bin/bash")
process.wait()
您还可以使用而不是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)
与进程交互:向stdin发送数据。从stdout和stderr读取数据,直到到达文件末尾。等待进程终止。运行命令失败的情况显然存在。
这是我的解决方法:
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)
def check_已完成(pfi,间隔=1,超时=100):
如果os.path.存在(pfi):
如果pfi.endswith('.nii.gz'):
mustend=time.time()+超时
while time.time()
这是一次疯狂的尝试,但您是以管理员的身份运行shell,而Blender是以普通用户的身份运行,还是以普通用户的身份运行shell
长话短说(很短),WindowsUAC是一种介于管理员和普通用户之间的隔离环境,所以这样的随机怪癖可能会发生。不幸的是,我记不起它的来源,我找到的最接近的是
我的问题与你的正好相反,wait()
陷入无限循环,因为我的python REPL是从管理shell启动的,无法读取常规用户子进程的状态。恢复到正常的用户shell使其得到修复。这不是我第一次从UAC的混乱中被咬到。你的问题给了我你正在使用的inpressionsubprocess.Popen
notsubprocess.run
当使用run时它也不等待吗?我使用subprocess.run,它也不等待。如果你在os.P_WAIT
作为第一个参数?你说的“作为第一个参数”是什么意思?第一个参数。在您尝试调用的命令的参数之前。这是启动进程并告诉python等待进程完成的老方法。例如,当您从命令行运行D:/Test/run my script.sh
时,windows上会发生什么?它会立即返回吗?您能发布bash脚本吗?在某些情况下,这不起作用。例如,在我的例子中,这个过程是一个程序,它创建一个文件,然后访问该文件以在一段时间内修改其内容。subprocess.call会在程序仍在修改文件内容且进程仍在进行时创建文件,并将进程视为已完成。有什么解决办法吗?@SeF那么您正在做一些意想不到的事情——文档非常明确地说明了函数的工作方式。也许你正在分岔或执行另一个进程?多亏了所有参与赏金的人,这个答案提出了一个替代等待命令的方法,它似乎并不总是有效。os.system
在某些情况下很好,但并不总是如此。他可能只是在调用二进制文件时出错,所以建议使用os.system并不是真正相关的。