PHP is so easy, it's made web coders out of three-year-olds. Now, move that skill to the CLI!
These days, it's rare to find a person who works with computers of any kind for a living who has not gotten hooked on PHP. The barrier to entry for coding PHP for the Web is a bit lower than coding Perl CGI scripts, if only because you don't have to compile PHP scripts in order to run them. I got hooked on PHP early on, but I no longer code much for the Web. What I have discovered, however, is that PHP is a very handy tool for creating command-line scripts, and even one-liners on the command line.
Go to the PHP.net function reference (http://www.php.net/manual/en/funcref.php) and check out what PHP has to offer, and you'll soon find that lots of PHP features of PHP are perfect for command-line programming. PHP has built-in functions for interfacing with syslog, creating daemons, and utilizing streams and sockets. It even has a suite of POSIX functions such as getpwuid
and getpid
.
For this hack, I'll be using PHP5 as supplied in the Fedora Core 4 distribution. PHP is readily available in binary format for SUSE, Debian, Red Hat, Fedora, Mandrake, and other popular distributions. Some distros have not yet made the move to PHP5, but they'll likely get there sooner rather than later.
Obviously, the actual code I use in this hack will be of limited use to you. The idea is really to make you think outside the box, using skills you already have, coding in PHP and applying it to something unconventional like system administration.
Let's have a look at some code. This first script is really simple; it's a simplified version of a script I use to avoid having to use the standard
ldapsearch tool with a whole bunch of flags. For example, if I want to search a particular server in another department for users with the last name Jones and get back the distinguished name (dn
) attribute for each of these users, here's what I have to type:
$ldapsearch -x -h
ldap.linuxlaboratory.org
-b"dc=
linuxlaboratory,dc=org
" '(sn=Jones)' dn
Yucky. It's even worse if you have to do this type of search often. I suppose you could write a shell script, but I found that PHP was perfectly capable of handling the task without relying on the ldapsearch tool being on the system at all. In addition, PHP's universality is a big plus—everyone in my group has seen PHP before, but some of them code in tcsh, which is different enough from ksh or bash to be confusing. Don't forget that the code you write today will become someone else's problem if a catastrophic bug pops up while you're on a ship somewhere sipping margaritas, far from a cell phone tower. Anyway, here's my script, which I call dapsearch:
#!/usr/bin/php <?php $conn=ldap_connect("ldap.linuxlaboratory.org") or die("Connect failed\n"); $bind = ldap_bind($conn) or die("Bind failed\n"); $answer = ldap_search($conn, "dc=linuxlaboratory,dc=org", "($argv[1])") ; $output = ldap_get_entries($conn, $answer); for ($i=0; $i < count($output); $i++) { if(!isset($output[$i])) break; echo $output[$i]["dn"]."\n"; } echo $output["count"]." entries returned\n"; ?>
There are a couple of things to note in the code above. On the first line is your everyday "shebang" line, which contains the path to the binary that will run the code, just like in any other shell or Perl script. If you're coding on your desktop machine for later deployment on a machine you don't control, you might replace that line with one that looks like this:
#!/usr/bin/env php
This does away with any assumption that the PHP binary is in a particular directory by doing a standard PATH
search for it, which can be more reliable.
In addition, you'll notice that the <?php
and ?>
tags are there in the shell script, just like they are in web scripts. This can be useful in cases where you have static text that you'd like output to the screen, because you can put that text outside the tags instead of using echo statements. Just close the tag, write your text, then open a new set of tags, and the parser will output your text, then start parsing PHP code when the tags open again.
Also, you can see I've simplified things a bit by hard-coding the attribute to be returned (the dn
attribute), as well as the server to which I'm connecting. This script can easily be altered to allow for that information to be passed in on the command line as well. Everything you pass on the command line will be in the argv
array.
Save the above script to a file called dapsearch, make it executable, and then run it, passing along the attribute for which you want to search. In my earlier ldapsearch command, I wanted the distinguished name attributes of all users with the last name "Jones." Here's the (greatly shortened) command I run nowadays to get that information:
$dapsearch sn=
Jones
This calls the script and passes along the search filter, which you'll see referenced in the code as $argv
[1]. This might look odd to Perl coders who are used to referencing a lone argument as either @_, $_
,or $argv[0]
. In PHP, $argv[0]
returns the command being run, rather than the first argument handed to it on the command line.
Speaking of the argv
array, you can run into errors while using this feature if your installation of PHP doesn't enable the argv
and argc
arrays by default. If this is the case, the change is a simple one: just open up your php.ini file (the configuration file for the PHP parser itself) and set register_argc_argv
to on.
Get Linux Server Hacks, Volume Two now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.