Can't remember what you called that script you wrote a couple years ago? Was it foobar ... or maybe it was fooBar ... or was it ... never mind...
% findcmd foo foo_bar

You know there's some fancy grep installed, but need to be reminded of its name. Oh, yeah...

% findcmd grep zgrep grep egrep cgrep fgrep

findcmd is a script which searches through the directories in the Unix PATH variable for executable files matching a specified regular expression. The idea for this script was not mine; I had been using the Bourne shell script of the same name from the CD from the ever-excellent book, Unix Power Tools. This script served me well for years on solaris. After switching to Linux, I would get intermittent strange behavior. So, I hacked at the sed code until it seemed to be working again... until we upgraded to the latest version of Linux. That's when I decided it was time to re-code this in Perl.

While I was at it, I decided to extend its capabilities:

Here is the code:

#!/usr/bin/env perl use warnings; use strict; use Getopt::Long; use Pod::Usage; my $print_path; my $re; parse_args(); my @dirs = split /:/, $ENV{PATH}; for my $dirname (@dirs) { if (-d $dirname) { if (opendir my $DIR, $dirname) { my @xfiles = grep { -x "$dirname/$_" } # choose only executable +files grep { !-d "$dirname/$_" } # reject directories grep { /$re/ } # pattern match readdir $DIR; closedir $DIR; for (@xfiles) { if ($print_path) { print "$dirname/$_\n"; } else { print "$_\n"; } } } } } exit; sub parse_args { my ($help, $sens); GetOptions( 'sens' => \$sens, 'path' => \$print_path, 'help' => \$help ) or pod2usage(); $help and pod2usage(-verbose => 2); if (@ARGV) { my $pat = shift @ARGV; $re = ($sens) ? qr/$pat/ : qr/$pat/i; } else { pod2usage('Error: regex required.'); } @ARGV and pod2usage("Error: unexpected args: @ARGV"); } =head1 NAME findcmd =head1 SYNOPSIS findcmd [options] regex Options: -help Verbose help -path Print out full directory paths also -sens Case-sensitive [default is case-insensitive] =head1 DESCRIPTION Search through the directories in the Unix PATH variable for executable files matching a specified regular expression. The names of all the commands which match will be printed to STDOUT. This is based on the I<findcmd> script from the CD that comes with the I<Unix Power Tools> book. It is important to note that neither aliases nor shell built-ins (I<cd>, I<which>, etc.) will be printed since neither is found in directories in the PATH variable. Any directories listed in the PATH variable which do not exist or are not readable will be silently ignored. Duplicate directories will not be removed. =head1 ARGUMENTS =over 4 =item regex A regular expression is required. The regex may be a simple string, such as C<foo>, or it may be a more complicated expression, such as C<^foo.*bar\d>. The regex syntax is Perl; it should not be confused with shell wilcard syntax or the syntax for other common Unix utilitie +s, such as I<sed> or I<grep>. It is best to quote the regex to prevent interaction with the shell. =back =head1 OPTIONS All options can be abbreviated. =over 4 =item sens By default, the regular expression is case-insensitive. So, if the inp +ut regex is C<foo>, it will match C<foo> as well as C<FOO> and C<Foo>, et +c. To use case-sensitive, use the C<-sens> option. findcmd -sens foo =item path By default, only the command name is printed. To instead print the ful +l directory path to the command, use the C<-path> option. findcmd -path foo =item help Show this verbose usage information. =back =head1 EXAMPLES Match a command name exactly (C<gnuplot>), and print the full directory path. This provides the same functionality as the I<whereiz> utility from I<Unix Power Tools>. findcmd -sens -path '^gnuplot$' Find all executable files in all path directories: findcmd . Find commands which begin with a dot: findcmd '^\.' Find commands with strange characters (not word, period, plus, dash): findcmd '[^\w.+-]' Find commands with a literal, case-sensitive "-s": findcmd -sens '\-s' =head1 SEE ALSO Refer to the following book: Unix Power Tools 2nd Edition Jerry Peek, Tim O'Reilly and Mike Loukides O'Reilly & Associates, Inc. =cut

Constructive criticism, suggestions for improvements and bug reports are welcome.


In reply to Finding commands in Unix PATH by toolic

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.