我在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')
答案 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攻击。