Karim
Karim

Reputation: 1546

Python: subprocess.Popen and subprocess.call hang

I have a problem using the subprocess.Popen or subprocess.call when I use them to execute a command lines that generates a lot of output, the python scripts hangs, but what is weird that after waiting for a while, while the script is in its hanging state, I find that the job commanded by the cmd line has been done, and only the script is hung out.

subprocess.call(cmd, shell = True)
#OR
subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subprocess.PIPE, shell = True)
# HANGS HERE
print "show something after subprocess"

Note that the last print is never executed, but actually the cmd has been executed.

Note also the cmd is related to the serial port, so when I plug out the serial cable, everything become fine, and the last print statetement get executed. But when I use the terminal everything is fine even if the serial is plugged in, it only occurs with the python script.

Thanks a lot

Upvotes: 18

Views: 21887

Answers (2)

glglgl
glglgl

Reputation: 91139

I don't understand why your first line doesn't work - as there are no stdin/stdout/stderr redirections, there is no need for blocking.

The second one is supposed to block if the process

  1. expects data via stdin or
  2. sends more data to stdout than a pipe can hold wothout being read.

But as your subprocess terminates correctly, I cannot see a reason for blocking as well. Are you sure that it really terminates?

Upvotes: 1

jcollado
jcollado

Reputation: 40424

According to the python documentation, subprocess.call runs the command and waits for it to complete, so it's equivalent to subprocess.Popen followed by Popen.wait.

However, the Popen.wait method documentation explicitly warns about the problem of buffer overflow and recommends to use Popen.communicate instead. Hence, the solution you're looking for should be something like:

import subprocess
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, shell=True)
stdout, stderr = process.communicate()
print "show something after subprocess"

Upvotes: 18

Related Questions