J'ai un script Python dans Blender où il a
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
suivi de nombreux autres codes qui dépendent de ce script Shell pour finir. Qu'est-ce qui se passe, c'est qu'il n'attend pas la fin, je ne sais pas pourquoi? J'ai même essayé d'utiliser Popen
au lieu de call
comme indiqué:
p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
p1.wait()
et j'ai essayé d'utiliser commuincate mais cela n'a toujours pas fonctionné:
p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True).communicate()
ce script shell fonctionne parfaitement sur MacOS (après modification des chemins) et attend lorsque vous utilisez subprocess.call(['sh', '/userA/Test/run-my-script.sh'])
mais sous Windows, c’est ce qui se passe, j’exécute le script python ci-dessous dans Blender puis, une fois que celui-ci est entré dans la ligne de sous-processus, Git bash
est ouvert et exécute le script Shell tant que Blender n’attend pas la fin du processus, imprime simplement Hello
dans sa console sans en attendant que le Git Bash soit terminé. De l'aide?
import bpy
import subprocess
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
print('Hello')
Vous pouvez utiliser subprocess.call
pour faire exactement cela.
sous-processus .call (arguments, *, stdin = Aucun, stdout = Aucun, stderr = Aucun, Shell = False, délai d'expiration = Aucun)
Exécutez la commande décrite par args. Attendez que la commande soit terminée, puis renvoyez l'attribut returncode.
Edit: Je pense avoir une idée de ce qui se passe. La commande fonctionne sur votre Mac car les Macs, je crois, prennent en charge Bash dès la sortie de la boîte (au moins quelque chose d’équivalent du point de vue fonctionnel) alors que sous Windows, elle tente de lancer un fichier ".sh" et se déclenche. Git Bash que je présume effectue quelques fourches lors du démarrage.
A cause de ce Python pense que votre script est terminé, le PID est parti.
Si j'étais vous, je ferais ceci:
tempfile
.Espérons que cela a du sens.
Vous pouvez utiliser l'API Popen.communicate.
p1 = subprocess.Popen(os.path.abspath('D:/Test/run-my-script.sh'),Shell=True)
sStdout, sStdErr = p1.communicate()
La commande
Popen.communicate(input=None, timeout=None)
Interagir avec le processus: envoyer des données à stdin. Lire les données de stdout et stderr jusqu'à la fin du fichier. Attendez que le processus se termine.
subprocess.run
attendra par défaut que le processus se termine.
Utilisez subprocess.Popen et Popen.wait:
process = subprocess.Popen(['D:/Test/run-my-script.sh'],Shell=True, executable="/bin/bash")
process.wait()
Vous pouvez également utiliser check_call () au lieu de Popen.
Vous pouvez utiliser os.system
, comme ceci:
import bpy
import os
os.system("sh "+os.path.abspath('D:/Test/run-my-script.sh'))
print('Hello')
Il y a apparemment des cas où la commande d'exécution échoue . Voici ma solution de contournement:
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)
Un essai sauvage, mais exécutez-vous le Shell en tant qu'administrateur alors que Blender en tant qu'utilisateur ordinaire ou vice versa?
En bref (très court), Windows UAC est une sorte d’environnement isolé entre l’administrateur et l’utilisateur habituel, de telles aléas peuvent donc se produire. Malheureusement, je ne me souviens pas de la source, le plus proche que j'ai trouvé est ceci .
Mon problème était l'exact opposé du vôtre, la wait()
est restée coincée dans une boucle infinie parce que mon python REPL a été déclenché par un shell d'administrateur et n'a pas pu lire l'état du sous-processus utilisateur normal. Revenant à l'utilisateur normal, Shell l'a corrigé. Ce n'est pas la première fois que je me moque de ce snafu UAC.