Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Execute Process -> Block till it exits & Suppress Output

I'm using the following to execute a process and hide its output from Python. It's in a loop though, and I need a way to block until the sub process has terminated before moving to the next iteration.

subprocess.Popen(["scanx", "--udp", host], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
like image 561
Jason Gooner Avatar asked Apr 01 '10 16:04

Jason Gooner


2 Answers

Use subprocess.call(). From the docs:

subprocess.call(*popenargs, **kwargs)
Run command with arguments. Wait for command to complete, then return the returncode attribute. The arguments are the same as for the Popen constructor.

Edit:

subprocess.call() uses wait(), and wait() is vulnerable to deadlocks (as Tommy Herbert pointed out). From the docs:

Warning: This will deadlock if the child process generates enough output to a stdout or stderr pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

So if your command generates a lot of output, use communicate() instead:

p = subprocess.Popen(
    ["scanx", "--udp", host],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE)
out, err = p.communicate()
like image 175
Ayman Hourieh Avatar answered Oct 23 '22 08:10

Ayman Hourieh


If you don't need output at all you can pass devnull to stdout and stderr. I don't know if this can make a difference but pass a bufsize. Using devnull now subprocess.call doesn't suffer of deadlock anymore

import os
import subprocess

null = open(os.devnull, 'w')
subprocess.call(['ls', '-lR'], bufsize=4096, stdout=null, stderr=null)
like image 43
mg. Avatar answered Oct 23 '22 07:10

mg.