473,396 Members | 1,968 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

using subprocess for non-terminating command

Hi all,
Consider this scenario, where in I need to use subprocess to execute a
command like 'ping 127.0.0.1' which will have a continuous non-
terminating output in Linux.

# code
>>>import subprocess
process = subprocess.Popen('ping 127.0.0.1', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>>print process.pid # returns pid
print process.poll() # returns None!!! this is strange.
print process.stdout.read()
# This hangs at this point.
How should I handle these kind of commands (ping 127.0.0.1) with
subprocess module. I am using subprocess, instead of os.system because
at anypoint in time, I need access to stdout and stderr of execution.

Thanks,
Senthil

Jul 4 '07 #1
9 6444
How should I handle these kind of commands (ping 127.0.0.1) with
subprocess module. I am using subprocess, instead of os.system because
at anypoint in time, I need access to stdout and stderr of execution.
Ping, for one, allows you to set an upper bound on how long it runs
(the -c option). This is probably the cleanest approach if it's
available.

You can also send the subprocess signals if you need it to exit
(although, this is a unix thing so I'm not sure how portable it is).
You could emulate having a timeout on child.stdout.read by registering
a callback with Timer to kill the child.

Cheers,
Aaron

Jul 4 '07 #2
* zacherates <za********@gmail.com[2007-07-04 12:09:03]:
How should I handle these kind of commands (ping 127.0.0.1) with
subprocess module. I am using subprocess, instead of os.system because
at anypoint in time, I need access to stdout and stderr of execution.

Ping, for one, allows you to set an upper bound on how long it runs
(the -c option). This is probably the cleanest approach if it's
available.
Yes, I am aware of the ping -c option. But again even that does not help.
try
process = subprocess.Popen('ping -c 10 127.0.0.1', stdin=subprocess.PIPE,
shell=True)
process.stdout.read() # This will hang again.

I am not sure, why subprocess is behaving so.
You can also send the subprocess signals if you need it to exit
(although, this is a unix thing so I'm not sure how portable it is).
Yes, I have tried to kill and then get the standard output result.
But the result has been the same. I could not read the Popen returned file
object.
You could emulate having a timeout on child.stdout.read by registering
a callback with Timer to kill the child.
I dont know how to do this. I shall give it a try ( by looking around ) and
trying.

--
O.R.Senthil Kumaran
http://uthcode.sarovar.org
Jul 4 '07 #3
On 7/4/07, O.R.Senthil Kumaran <or*******@users.sourceforge.netwrote:
Yes, I am aware of the ping -c option. But again even that does not help.
try
process = subprocess.Popen('ping -c 10 127.0.0.1', stdin=subprocess.PIPE,
shell=True)
process.stdout.read() # This will hang again.
When I try that, it doesn't hang. Instead, I get the output of the
ping command pruinted to the screen, then the following exception:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read'

That's because you tied stdin to a pipe in your Popen call, but then
tried to read from stdout. Try this instead:
>>process = subprocess.Popen("ping -c 10 127.0.0.1",
stdout=subprocess.PIPE, shell=True)
>>process.stdout.readlines()
['PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.\n', '64 bytes from
127.0.0.1: icmp_seq=1 ttl=64 time=0.049 ms\n', '64 bytes from
127.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms\n', '64 bytes from
127.0.0.1: icmp_seq=3 ttl=64 time=0.040 ms\n', '64 bytes from
127.0.0.1: icmp_seq=4 ttl=64 time=0.033 ms\n', '64 bytes from
127.0.0.1: icmp_seq=5 ttl=64 time=0.033 ms\n', '64 bytes from
127.0.0.1: icmp_seq=6 ttl=64 time=0.030 ms\n', '64 bytes from
127.0.0.1: icmp_seq=7 ttl=64 time=0.032 ms\n', '64 bytes from
127.0.0.1: icmp_seq=8 ttl=64 time=0.028 ms\n', '64 bytes from
127.0.0.1: icmp_seq=9 ttl=64 time=0.030 ms\n', '64 bytes from
127.0.0.1: icmp_seq=10 ttl=64 time=0.039 ms\n', '\n', '--- 127.0.0.1
ping statistics ---\n', '10 packets transmitted, 10 received, 0%
packet loss, time 8991ms\n', 'rtt min/avg/max/mdev =
0.028/0.034/0.049/0.009 ms\n']

--
Jerry
Jul 4 '07 #4
O.R.Senthil Kumaran wrote:
* zacherates <za********@gmail.com[2007-07-04 12:09:03]:
>>How should I handle these kind of commands (ping 127.0.0.1) with
subprocess module. I am using subprocess, instead of os.system because
at anypoint in time, I need access to stdout and stderr of execution.
Ping, for one, allows you to set an upper bound on how long it runs
(the -c option). This is probably the cleanest approach if it's
available.

Yes, I am aware of the ping -c option. But again even that does not help.
try
process = subprocess.Popen('ping -c 10 127.0.0.1', stdin=subprocess.PIPE,
shell=True)
process.stdout.read() # This will hang again.

I am not sure, why subprocess is behaving so.
>You can also send the subprocess signals if you need it to exit
(although, this is a unix thing so I'm not sure how portable it is).

Yes, I have tried to kill and then get the standard output result.
But the result has been the same. I could not read the Popen returned file
object.
>You could emulate having a timeout on child.stdout.read by registering
a callback with Timer to kill the child.

I dont know how to do this. I shall give it a try ( by looking around ) and
trying.
Is it possible your ping implementation outputs to stderr?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------

Jul 4 '07 #5
* Jerry Hill <ma*********@gmail.com[2007-07-04 11:23:33]:
>
That's because you tied stdin to a pipe in your Popen call, but then
tried to read from stdout. Try this instead:
My mistake. I had just 'typed' the command in the mail itself and forgot to
include the stdin, stdout, and stderr and mentioned it as hung based on some
recollection.
>
>process = subprocess.Popen("ping -c 10 127.0.0.1",
stdout=subprocess.PIPE, shell=True)
>process.stdout.readlines()
I tried it again and found that giving the -c 10 returns a well defined
output.
Only when the program has executed and the output available, subprocess can
read through PIPE's stdout it seems ( not at any other time).
With killing, I loose the output.
>>process = subprocess.Popen('ping 10 127.0.0.1', stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
>>process.pid
3475
>>import os
import signal
os.kill(process.pid,signal.SIGINT)
process.stdout.read()
''
>># required output is lost!

--
O.R.Senthil Kumaran
http://uthcode.sarovar.org
Jul 4 '07 #6
Only when the program has executed and the output available, subprocess can
read through PIPE's stdout it seems ( not at any other time).
With killing, I loose the output.
This is untrue.
>>process.stdout.read() # Blocks until end of stream.
process.stdout.read(1) # Reads one character, only blocks if that character is unavailable.
As such you can read the needed chars from the child's STDOUT one at a
time. For example:

import os
import signal
import subprocess
import threading
import sys

stop = False
ping = subprocess.Popen('ping 127.0.0.1', shell = True, stdout =
subprocess.PIPE)

def kill():
global stop
stop = True
os.kill(ping.pid, signal.SIGTERM)

threading.Timer(5, kill).start()

while not stop:
sys.stdout.write(ping.stdout.read(1))

This solution let's you read from the stdout of a program that may
never terminate and time out after a certain amount of time but it's
not pretty. It's unix specific and introduces threads into a program
that doesn't need them. I'd go with trying to limit the time the
child runs through command line options if at all possible.

Cheers,
Aaron
Jul 4 '07 #7
On Jul 4, 12:29 pm, "O.R.Senthil Kumaran"
<orsent...@users.sourceforge.netwrote:
* Jerry Hill <malaclyp...@gmail.com[2007-07-04 11:23:33]:
That's because you tied stdin to a pipe in your Popen call, but then
tried to read from stdout. Try this instead:

My mistake. I had just 'typed' the command in the mail itself and forgot to
include the stdin, stdout, and stderr and mentioned it as hung based on some
recollection.
>>process = subprocess.Popen("ping -c 10 127.0.0.1",
stdout=subprocess.PIPE, shell=True)
>>process.stdout.readlines()

I tried it again and found that giving the -c 10 returns a well defined
output.
Only when the program has executed and the output available, subprocess can
read through PIPE's stdout it seems ( not at any other time).
With killing, I loose the output.
>process = subprocess.Popen('ping 10 127.0.0.1', stdin=subprocess.PIPE,

stdout=subprocess.PIPE, stderr=subprocess.PIPE,shell=True)
I think you meant ping -c 10 (and not ping 10). If you pass first arg
as string, are you sure you didn't get an exception? I get one if I
use 'ping -c 10 <ip-addr>' -- because looks like subprocess is
searching for an executable named as "ping -c 10 ..." (not just
'ping').
So I sent in a sequence and it all worked as expected (I didn't have
shell=True, but it shouldn't matter in getting the required output).

Try the sequence as first arg.
>>process = subprocess.Popen('ping -c 10 127.0.0.1', stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/auto/xxxkarthikxxx/python251/lib/python2.5/subprocess.py",
line 593, in __init__
errread, errwrite)
File "/auto/xxxkarthikxxx/python251/lib/python2.5/subprocess.py",
line 1079, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
>>process = subprocess.Popen('ping -c 10 127.0.0.1'.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>print process
<subprocess.Popen object at 0xb7580aac>
>>print process.pid
13435
>>print process.stdout.read()
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.025 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.006 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.005 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.004 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.011 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.007 ms
64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.020 ms
64 bytes from 127.0.0.1: icmp_seq=7 ttl=64 time=0.006 ms
64 bytes from 127.0.0.1: icmp_seq=8 ttl=64 time=0.006 ms
64 bytes from 127.0.0.1: icmp_seq=9 ttl=64 time=0.006 ms

--- 127.0.0.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9013ms
rtt min/avg/max/mdev = 0.004/0.009/0.025/0.007 ms, pipe 2
>>>
-- Karthik
>
>process.pid
3475
>import os
import signal
os.kill(process.pid,signal.SIGINT)
process.stdout.read()
''
># required output is lost!

--
O.R.Senthil Kumaranhttp://uthcode.sarovar.org

Jul 4 '07 #8
On Jul 4, 4:38 am, Phoe6 <orsent...@gmail.comwrote:
Hi all,
Consider this scenario, where in I need to use subprocess to execute a
command like 'ping 127.0.0.1' which will have a continuous non-
terminating output in Linux.

# code
>>import subprocess
process = subprocess.Popen('ping 127.0.0.1', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print process.pid # returns pid
print process.poll() # returns None!!! this is strange.
It's expected behavior. It means the child process is still running.
>>print process.stdout.read()

# This hangs at this point.
This too is expected behavior. 'ping <ip-addr>' runs forever
generating continuous output. It doesn't stop by itself.

read() reads until there is data available in the file object. Thus it
doesn't ever finish since the child never stops generating data.

If you do read(n), then it reads n bytes and returns.

How should I handle these kind of commands (ping 127.0.0.1) with
subprocess module. I am using subprocess, instead of os.system because
at anypoint in time, I need access to stdout and stderr of execution.
Using subprocess is good. Just ensure your child stops data generation
at some point. For ping, you can use '-c <num>' or some other
application, you can try closing it's stdin (e.g. cat, bc, gdb)

Thanks,
Karthik
Thanks,
Senthil

Jul 4 '07 #9
On 7/4/07, O.R.Senthil Kumaran <or*******@users.sourceforge.netwrote:
Only when the program has executed and the output available, subprocess can
read through PIPE's stdout it seems ( not at any other time).
With killing, I loose the output.
I think you have to read the data from the process's stdout before you
kill it. If you want to process the output of the program before it's
done, do something like this:

import subprocess
process = subprocess.Popen("ping 127.0.0.1", stdout=subprocess.PIPE, shell=True)
for i in xrange(10):
line = process.stdout.readline()
print "line:", repr(line)

Then you can decide to kill the subprocess when you have enough data,
or whatever.

Also, even though the output from ping appears to be pretty easy to
read, there can be problems with buffering when you connect a pipe to
the stdout of some programs. The pexpect faq talks a little bit about
that - http://pexpect.sourceforge.net/#faq . If you're working under
a unix system, pexpect is really useful for automating interactive
programs that are otherwise difficult to work with.

--
Jerry
Jul 5 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Batista, Facundo | last post by:
I tested the following simple code: ----------------- from Tkinter import * class App: def __init__(self, master): frame = Frame(master)
17
by: Michael McGarry | last post by:
Hi, I am just starting to use Python. Does Python have all the regular expression features of Perl? Is Python missing any features available in Perl? Thanks, Michael
4
by: Nicolas Fleury | last post by:
Hi, I want to use the subprocess module (or any standard Python module) to run a process: - which stdout and stderr can each be redirected to any file-like object (no fileno function). - can be...
2
by: Do Re Mi chel La Si Do | last post by:
Hi! This script (under Win-XP + P-2.4.1) : import subprocess p1=subprocess.Popen(r'cmd /cdir *.* /S /W /B', stdout=subprocess.PIPE) chaineretour=p1.stdout.read() run OK if called from...
4
by: Marc Carter | last post by:
I am trying to rewrite a PERL automation which started a "monitoring" application on many machines, via RSH, and then multiplexed their collective outputs to stdout. In production there are lots...
3
by: Darren Dale | last post by:
I'm a developer on the matplotlib project, and I am having trouble with the subprocess module on windows (Python 2.4.2 on winXP). No trouble to report with linux. I need to use _subprocess instead...
5
by: Cameron Laird | last post by:
Question: import subprocess, StringIO input = StringIO.StringIO("abcdefgh\nabc\n") # I don't know of a compact, evocative, and # cross-platform way to exhibit this behavior. # For now, depend...
9
by: Clodoaldo Pinto Neto | last post by:
Output from the shell: $ set | grep IFS IFS=$' \t\n' Output from subprocess.Popen(): "IFS=' \t\n" Both outputs for comparison:
5
by: Grant Edwards | last post by:
I'm trying to use the py-gnuplot module on windows, and have been unable to get it to work reliably under Win2K and WinXP. By default, it uses popen(gnuplotcmd,'w'), but in some situations that...
1
by: Mark Shewfelt | last post by:
Hello, I am attempting to use Popen() in a Windows service. I have a small Win32 .exe that I normally run through the os.popen2() function. I've written a class to work with the input and output...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.