Recipe 18.23 Reading Standard Output from a Program
18.23.1 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.
18.23.2 Solution
To read the entire contents of a program's output,
use the
backtick (') operator:
$routing_table = `/sbin/route`;
To read the output incrementally, open a pipe with popen(
):
$ph = popen('/sbin/route','r') or die($php_errormsg);
while (! feof($ph)) {
$s = fgets($ph,1048576) or die($php_errormsg);
}
pclose($ph) or die($php_errormsg);
18.23.3 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, this
command:
$s = `/usr/bin/free`;
puts this 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. This example prints information about
recent Unix system logins formatted as an
HTML table. It uses the
/usr/bin/last command:
// 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,80) 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>';
18.23.4 See Also
Documentation on popen( ) at
http://www.php.net/popen, pclose(
) at http://www.php.net/pclose, and
the backtick operator at
http://www.php.net/language.operators.execution;
safe mode is documented at
http://www.php.net/features.safe-mode.
|