So I wrote a script that accesses a bunch of servers using nc on the command line, and originally I was using Python's commands module and calling commands.getoutput() and the script ran in about 45 seconds. Since commands is deprecated, I want to change everything over to using the subprocess module, but now the script takes 2m45s to run. Anyone have an idea of why this would be?
What I had before:
output = commands.getoutput("echo get file.ext | nc -w 1 server.com port_num")
now I have
p = Popen('echo get file.ext | nc -w 1 server.com port_num', shell=True, stdout=PIPE)
output = p.communicate()[0]
Thanks in advance for the help!
I would expect
subprocess
to be slower thancommand
. Without meaning to suggest that this is the only reason your script is running slowly, you should take a look at thecommands
source code. There are fewer than 100 lines, and most of the work is delegated to functions fromos
, many of which are taken straight from c posix libraries (at least in posix systems). Note thatcommands
is unix-only, so it doesn't have to do any extra work to ensure cross-platform compatibility.Now take a look at
subprocess
. There are more than 1500 lines, all pure Python, doing all sorts of checks to ensure consistent cross-platform behavior. Based on this, I would expectsubprocess
to run slower thancommands
.I timed the two modules, and on something quite basic,
subprocess
was almost twice as slow ascommands
.Swiss suggests some good improvements that will help your script's performance. But even after applying them, note that
subprocess
is still slower.Assuming you are performing the above command many times in a row, this will add up, and account for at least some of the performance difference.
In any case, I am interpreting your question as being about the relative performance of
subprocess
andcommand
, rather than being about how to speed up your script. For the latter question, Swiss's answer is better.There seems to be at least two separate issues here.
First, you are improperly using Popen. Here are the problems I see:
Here is a corrected version of your code
Second, the fact that you suggest it ends faster when manually run than when run through subprocess suggests that the issue here is that you are not passing the correct string to
nc
. What is probably happening is that the server is waiting for a terminating string to end the connection. If you are not passing this, then the connection probably remains open until it times out.Run
nc
manually, figure out what the terminating string is, then update the string passed tocommunicate
. With these changes it should run much faster.