[CMI.PM] Trapping STDOUT in-process?

Mitch Kutzko mitch at ncsa.uiuc.edu
Thu Oct 7 21:02:41 CDT 2004


Hi, folks -- Is there a way for me to read STDOUT on the fly, as it
happens, before the command I'm execing is complete?

Background:

I need to write a script that returns the names of all the hosts involved
in a traceroute.  This is fairly simple:

------------------------------------------------------------
#!/usr/bin/perl -w

use strict;

my $target = "qbridge.bu.edu";  # Default target
if (defined $ARGV[0]) {         # If they gave a different target
        $target = $ARGV[0];
}

$target = lc($target);          # Lowercase it

# Get the output text for parsing, and supress console output
my @results = qx/traceroute $target/;
my @errors = qx/traceroute $target 2>&1/;

if (!@results && @errors) {             # What went wrong?
        print "Uh-oh:\n at errors\n";
        exit;
}


my $lth = scalar @results;      # Get number of lines (= # of hops)
my $hostname = `hostname -f`;   # Get local  hostname (-f may not work some
OSs)
chomp $hostname;                # Remove trailing space

print "Results: $lth hops from $hostname to $target\n";

# Iterate over lines/hops to get hostnames
my $ii=0;
for ($ii=0;$ii<$lth;$ii++) {
        my @spot = split ' ', $results[$ii];    # Break on word boundaries
        $spot[1] = lc($spot[1]);                # Lowercase the name
        print "$ii) $spot[1]\n";                # Print it
}

exit;
------------------------------------------------------------


If the host is pingable, or if the host doesn't actually exist, this works
fine.

The problem is the case in which this is likely to be used most often, in
which a legitimate host doesn't have a route to it at the moment (which is
why the diagnostic is being run in the first place), and so generates
output like this:

[mitch at jhereg advisor]$ traceroute dyn09.iacc-t21.ndsu.nodak.edu
traceroute to dyn09.iacc-t21.ndsu.nodak.edu (134.129.71.204), 30 hops max,
38 byte packets
 1  netdev98-254 (141.142.98.254)  12.878 ms  0.381 ms  0.341 ms
 2  sbr0-vlan116.gw.ncsa.edu (141.142.0.65)  0.459 ms  0.543 ms  0.409 ms
 3  198.17.196.2 (198.17.196.2)  3.025 ms  2.980 ms  3.038 ms
 4  chin-mren-ge.abilene.ucaid.edu (198.32.11.97)  3.042 ms  3.178 ms
3.010 ms
 5  iplsng-chinng.abilene.ucaid.edu (198.32.8.77)  175.039 ms  237.742 ms
256.378 ms
 6  mn-abilene.northernlights.gigapop.net (192.42.152.170)  27.838 ms
27.764 ms  27.763 ms
 7  ndsu-i2r.northernlights.gigapop.net (192.42.152.173)  34.522 ms  34.154
ms  34.337 ms
 8  vlan-107.cc.ndsu.NoDak.edu (134.129.107.100)  44.434 ms  34.303 ms
34.304 ms
 9  * * *
10  * * *


The problem with my script above is that it relies on the command actually
either completing or failing.  This case is "in-process", and so does neither.

When run via my script, no output occurs at all, as the qx// never comes back.

So my question is:

Is there a way for me to read STDOUT on the fly, as it happens, before the
command I'm execing is complete?

Thanks!

Mitch
--
Mitch Kutzko | mitch at dast.nlanr.net | mitch at ncsa.uiuc.edu | 217-333-1199
http://hobbes.ncsa.uiuc.edu/


More information about the Champaign-Urbana mailing list