% 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.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Finding commands in Unix PATH
by ambrus (Abbot) on Jun 04, 2008 at 18:48 UTC | |
|
Re: Finding commands in Unix PATH
by Fletch (Bishop) on Jun 04, 2008 at 19:48 UTC | |
by jdporter (Paladin) on Jun 05, 2008 at 13:50 UTC | |
by Fletch (Bishop) on Jun 05, 2008 at 14:00 UTC |