Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocess.call not waiting for process to finish blender

I have a python script in blender where it has

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

followed by many other code which depends on this shell script to finish. What happens is that it doesn't wait for it to finish, I don't know why? I even tried using Popen instead of call as shown:

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

and I tried using commuincate but it still didn't work:

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

this shell script works great on MacOS (after changing paths) and waits when using subprocess.call(['sh', '/userA/Test/run-my-script.sh'])

but on Windows this is what happens, I run the below python script in Blender then once it gets to the subprocess line Git bash is opened and runs the shell script while blender doesn't wait for it to finish it just prints Hello in its console without waiting for the Git Bash to finish. Any help?

import bpy
import subprocess
subprocess.call(os.path.abspath('D:/Test/run-my-script.sh'),shell=True)
print('Hello')
like image 524
Tak Avatar asked Apr 11 '17 23:04

Tak


People also ask

Does subprocess call wait for completion?

The subprocess module provides a function named call. This function allows you to call another program, wait for the command to complete and then return the return code.

What is difference between subprocess Popen and call?

Popen is more general than subprocess. call . Popen doesn't block, allowing you to interact with the process while it's running, or continue with other things in your Python program. The call to Popen returns a Popen object.

Is subprocess Popen a blocking call?

Popen is nonblocking. call and check_call are blocking. You can make the Popen instance block by calling its wait or communicate method.

What is the difference between subprocess and process?

To make this clearer, let's recall that a process is a sequence of activities that has a beginning and a definite end. So while a subprocess is an activity that can be subdivided into smaller parts, a task is an activity that has no subdivisions, it's just a single task e.g.,. Confirm delivery.


2 Answers

You can use subprocess.call to do exactly that.

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False, timeout=None)

Run the command described by args. Wait for command to complete, then return the returncode attribute.

Edit: I think I have a hunch on what's going on. The command works on your Mac because Macs, I believe, support Bash out of the box (at least something functionally equivalent) while on Windows it sees your attempt to run a ".sh" file and instead fires up Git Bash which I presume performs a couple forks when starting.

Because of this Python thinks that your script is done, the PID is gone.

If I were you I would do this:

  • Generate a unique, non-existing, absolute path in your "launching" script using the tempfile module.
  • When launching the script, pass the path you just made as an argument.
  • When the script starts, have it create a file at the path. When done, delete the file.
  • The launching script should watch for the creation and deletion of that file to indicate the status of the script.

Hopefully that makes sense.

like image 200
joebeeson Avatar answered Oct 24 '22 04:10

joebeeson


You can use Popen.communicate API.

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

The command

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

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for the process to terminate.

like image 44
Pankaj Avatar answered Oct 24 '22 04:10

Pankaj