Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python subprocess.call blocking

Tags:

python

I am trying to run an external application in Python with subprocess.call. From what I've read it subprocess.call isn't supposed to block unless you call Popen.wait, but for me it is blocking until the external application exits. How do I fix this?

like image 741
dpitch40 Avatar asked Jan 09 '13 20:01

dpitch40


People also ask

Does subprocess Popen block?

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

Does subprocess call wait?

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. It accepts one or more arguments as well as the following keyword arguments (with their defaults): stdin=None, stdout=None, stderr=None, shell=False.

How can we avoid shell true in subprocess?

From the docs: args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).


2 Answers

You're reading the docs wrong. According to them:

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

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

like image 193
g.d.d.c Avatar answered Nov 16 '22 20:11

g.d.d.c


The code in subprocess is actually pretty simple and readable. Just see the 3.3 or 2.7 version (as appropriate) and you can tell what it's doing.

For example, call looks like this:

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

You can do the same thing without calling wait. Create a Popen, don't call wait on it, and that's exactly what you want.

like image 27
abarnert Avatar answered Nov 16 '22 21:11

abarnert