#native_company# #native_desc#
#native_cta#

PHP and Shell Scripting: Using Pipes Page 2

By Peter Shaw
on February 12, 2009

As you can see the outputs are very similar, but not identical, however this is not an article about shell programming in general, it’s about putting PHP to some advanced uses. You can see from the examples above that commands are joined with the vertical bar character ‘|’ as this is the pipe character, and to cut this short basically means take the output of one command and feed to the next via the standard input stream.
This means if we read the standard input stream using the php file stream ‘php://stdin’ then we can use PHP to construct blocks of code that can participate in the filter chain.
Enough talking already, give us some code!!!!
Ok ok, I hear you. So by way of an example to show what I??m on about, we’ll put together a small example under Linux that shows what those file permission flags in a file listing mean.
First, if we do an ‘ls -al’ we should see something like this:

<code>
drwx------  2 shawty users      4096 2006-04-10 23:51 .ssh
-rw-r--r--  1 shawty users       193 2007-10-25 10:43 staaus.cap
-rw-r--r--  1 shawty users     11627 2007-10-27 14:05 staceymail2
-rw-r--r--  1 shawty users     18737 2007-10-28 00:24 staceymail3
-rw-r--r--  1 shawty users     34040 2007-10-28 16:10 staceymail4
-rw-r--r--  1 shawty users    182891 2007-10-26 09:28 stacymail
-rw-r--r--  1 shawty shawty     3642 2008-10-29 17:02 startup
-rw-r--r--  1 shawty shawty     4124 2008-10-29 17:03 startup-org
-rw-r--r--  1 shawty users        55 2006-06-03 01:51 suck.newrc
-rw-r--r--  1 shawty users        50 2006-06-03 01:47 sucknewsrc
-rw-r--r--  1 shawty users         0 2008-05-15 17:20 .sudo_as_admin_successful
-rw-r--r--  1 shawty users     23067 2006-10-12 22:34 telnet.pl
-rw-r--r--  1 shawty users   9231834 2006-04-18 14:21 termine
</code>

The first thing we need to do here is to read this into a PHP script.

<code>
<?php

  // Open PHP's standard input stream
  $input_stream = fopen("php://stdin","r");

  // Array to store the received data
  $lines = array();

  // Loop & process while we receive lines
  while($line = fgets($input_stream,4096)) // Note 4k lines, should be ok for most purposes
  {
    //Store each line in the array, ensuring we chop off the line ends
    $lines[] = trim($line);
  }

  fclose($input_stream);

  print_r($lines);

?>
</code>
    

If you run this from a Linux command line using ‘ls -al | php -q fancydir.php’ (replace php file name as required), you’ll get something like the following:

<code>
shawty@poweredge:~/Articles_PHP$ ls -al ../ | php -q fancydir.php
Array
(
    [0] => total 54676
    [1] => drwxr-xr-x 46 shawty users      4096 2009-01-29 20:01 .
    [2] => drwxr-xr-x 14 root   root       4096 2009-01-13 17:17 ..
    [3] => -rw-r--r--  1 shawty users         1 2006-11-15 02:24 2
    [4] => drwxr-xr-x 10 shawty users      4096 2008-05-14 17:11 20gdrive
    [5] => drwxr-x---  6 shawty users      4096 2007-04-30 16:14 4grec1
    [6] => drwx------  2 shawty users      4096 2006-05-14 17:31 a.b.p.v.files
    [7] => -rw-r--r--  1 shawty users   1863991 2006-03-06 14:24 abs-guide.pdf
    [8] => -rw-r--r--  1 shawty users         0 2006-05-23 22:42 .addressbook
    [9] => -rw-------  1 shawty users      2285 2006-05-23 22:42 .addressbook.lu
    [10] => drwx------  2 shawty users      4096 2008-05-15 17:42 .aptitude
    [11] => drwxr-xr-x  2 shawty shawty     4096 2009-01-29 20:01 Articles_PHP
    [12] => drwxr-xr-x  3 shawty users      4096 2006-06-11 01:34 baks
    [13] => -rw-------  1 shawty users     15190 2009-01-29 12:56 .bash_history
    [14] => -rw-r--r--  1 shawty users       220 2008-05-15 16:41 .bash_logout
    [15] => -rw-r--r--  1 shawty users      2298 2008-05-15 16:41 .bashrc
    [16] => drwxr-xr-x  2 shawty users      4096 2006-08-07 14:39 belkinbt
    [17] => drwx------  2 shawty users      4096 2006-08-22 21:16 .cedit
  ==SNIP==
</code>
    

As you can see, the directory listing is in an array, line by line as sent to the script. We can now use this array to go over each line and redisplay it, something like this:

<code>
$count = 1;
foreach($lines as $line)
{
  print $count . " : " . $line . "n";
  $count++;
}
</code>
    

This would give you a number listing something like the following:

<code>
1 : drwxr-xr-x 46 shawty users      4096 2009-01-29 20:01 .
2 : drwxr-xr-x 14 root   root       4096 2009-01-13 17:17 ..
3 : -rw-r--r--  1 shawty users         1 2006-11-15 02:24 2
4 : drwxr-xr-x 10 shawty users      4096 2008-05-14 17:11 20gdrive
5 : drwxr-x---  6 shawty users      4096 2007-04-30 16:14 4grec1
6 : drwx------  2 shawty users      4096 2006-05-14 17:31 a.b.p.v.files
7 : -rw-r--r--  1 shawty users   1863991 2006-03-06 14:24 abs-guide.pdf
8 : -rw-r--r--  1 shawty users         0 2006-05-23 22:42 .addressbook
</code>