Reading Standard Output from a Program






Reading Standard Output from a Program

Problem

You want to read the output from a program; for example, you want the output of a system utility such as route(8) that provides network information.

Solution

To read the entire contents of a program's output, use the backtick (`) operator, as in Figure.

Running a program with backticks

<?php
$routing_table = `/sbin/route`;
?>

To read the output incrementally, open a pipe with popen( ), as in Figure.

Reading output from popen( )

<?php
$ph = popen('/sbin/route','r') or die($php_errormsg);
while (! feof($ph)) {
    $s = fgets($ph)            or die($php_errormsg);
}
pclose($ph)                    or die($php_errormsg);
?>

Discussion

The backtick operator, which is not available in safe mode, executes a program and returns all its output as a single string. On a Linux system with 448 MB of RAM, the command $s = `/usr/bin/free`; puts the following multiline string in $s:

             total       used       free     shared    buffers     cached
Mem:        448620     446384       2236          0      68568     163040
-/+ buffers/cache:     214776     233844
Swap:       136512          0     136512

If a program generates a lot of output, it is more memory efficient to read from a pipe one line at a time. If you're printing formatted data to the browser based on the output of the pipe, you can print it as you get it. Figure prints information about recent Unix system logins formatted as an HTML table. It uses the /usr/bin/last command.

Printing recent logins with popen( )

<?php
// print table header
print<<<_HTML_
<table>
<tr>
 <td>user</td><td>login port</td><td>login from</td><td>login time</td>
 <td>time spent logged in</td>
</tr>
_HTML_;

// open the pipe to /usr/bin/last
$ph = popen('/usr/bin/last','r') or die($php_errormsg);
while (! feof($ph)) {
    $line = fgets($ph) or die($php_errormsg);

    // don't process blank lines or the info line at the end
    if (trim($line) && (! preg_match('/^wtmp begins/',$line))) {
        $user = trim(substr($line,0,8));
        $port = trim(substr($line,9,12));
        $host = trim(substr($line,22,16));
        $date = trim(substr($line,38,25));
        $elapsed = trim(substr($line,63,10),' ()');

        if ('logged in' == $elapsed) {
            $elapsed = 'still logged in';
            $date = substr_replace($date,'',-5);
        }

        print "<tr><td>$user</td><td>$port</td><td>$host</td>";
        print "<td>$date</td><td>$elapsed</td></tr>\n";
    }
}
pclose($ph) or die($php_errormsg);

print '</table>';
?>

See Also

Documentation on popen( ) at http://www.php.net/popen, pclose( ) at http://www.php.net/pclose, the backtick operator at http://www.php.net/language.operators.execution, and safe mode at http://www.php.net/features.safe-mode.



 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows