Python Forum

Full Version: reading from two or more pipes
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i got some example code online that showed me how to read from a pipe without using .communicate() which waits for the child process to exit, which may take a very long time for some things.  i condensed the example and change some parts as shown:

from __future__ import print_function
from sys import argv, stderr, stdout, version
import subprocess
def main(args):
    process = subprocess.Popen(['ping','-c','8','8.8.4.4'], stdout=subprocess.PIPE)
    while True:
        output = process.stdout.readline()
        if len(output)<1 and process.poll() != None: return
        print(output.strip())

if __name__ == '__main__':
    main(argv)
i did not put in that blank line (line 10).  my own file i ran to test the code does not have it and it works fine without it in both python 2 and python 3.  it gets put in there every time i do Preview Post.  what's up with that?

now what i want to do is run two or more processes (such as multiple pings) and read both from separate pipes so i know which process's output i am getting. i've done this a lot in C which involved the poll() or select() system calls to know which pipe had data ready to read.  do i need to do the same in python or is there a library that provides this (prefer one that comes in python so others don't have to do some other install to use my program).  any ideas, suggestions, or googling terms to learn what python can do along these lines?
How about something like
import subprocess

ips = [...]
processes = [subprocess.Popen(['ping', '-c', '8', ip], stdout=subprocess.PIPE) for ip in ips]
while True:
   for process in processes:
       print(process.stdout.readline().strip())

   if all(process.poll() is not None for process in processes):
       exit()
(I realize you could exit with unread stdout here, but I'm hoping this code suggests how to solve your problem.)
oooh, i didn't know you could do that with all() without [].  "other people's code" (opc) can very often help the learning process.

what i ultimately want to do is show differences between hosts, so i need to update the right stuff after each readline and do the appropriate output, like updating a graph (for example scaling other hosts up when one host has a long ping delay).
one task will be comparing pings outside a tunnel (between the tunnel endpoints) to pings inside the tunnel (between the tunnel interfaces).

yeah, i could merge all the responses an read it as one stream and check the ip addresses in the responses, but i really don't want to risk the issues with that.


i may need to have the code wake up on time events such as to have metrics updated due to the lack of a response.  but that can be done (if all else fails, add a ping to localhost).

now why did an empty line get added to my post?