#!/usr/pkg/bin/perl -wl
# finbin - find binaries in the user's PATH
# See the POD at the end of the file for documentation.
use strict;
use Getopt::Std;
my %opts;
our $VERSION = 1.2;
getopts('fFp:qx', \%opts) || exit 2;
argLoop: for (@ARGV) {
for my $d (split /:/, $opts{p} || $ENV{PATH}) {
$d = '.' if $d eq '';
for (grep { -e && (!$opts{x} || -x) } glob "$d/$_") {
# The `-e' is for when the glob() fails to find a match.
exit 0 if $opts{q};
print;
exit 0 if $opts{f};
next argLoop if $opts{F};
}
}
}
exit 1 if $opts{q};
sub HELP_MESSAGE {
select shift;
print <<EOT;
Usage: $0 [-F | -f | -q] [-x] [-p path] pattern ...
Type `man finbin` for more information.
EOT
exit 0;
}
__END__
=pod
=head1 NAME
B<finbin> - find binaries in the user's PATH
=head1 SYNOPSIS
B<finbin> [B<-F> | B<-f> | B<-q>] [B<-x>] [B<-p> I<path>] I<pattern> ...
=head1 DESCRIPTION
B<finbin> searches the user's PATH for any files matching the given I<pattern>
and prints the results to standard output. It is intended as a replacement for
the inconsistently implemented L<which(1)> and L<whereis(1)> commands.
If B<finbin> is given more than one operand, it searches for each one
individually and prints out the results as it finds them. Each operand is
interpreted as a shell wildcard pattern to match against the contents of each
directory in the PATH. If no wildcards are present in an operand, it is
treated as the basename of a program to look for; if wildcards are present,
they may have to be escaped or quoted in order to avoid interpolation by one's
shell.
=head1 OPTIONS
=over
=item B<-F>
Print out only the first match found for each operand.
=item B<-f>
Exit immediately after finding the first match.
=item B<-p> I<path>
Use I<path> as the path to search rather than the user's PATH environment
variable. Directories in I<path> must be separated by colons. An empty string
in I<path> is interpreted as referring to the current directory.
=item B<-q>
Do not print anything; instead, exit with a status of 0 if any matches were
found, 1 otherwise.
=item B<-x>
Only find matches that the user has execute permission for.
=back
=head1 RESTRICTIONS
Due to Getopt::Std's parsing of all options at once, rather than parsing them
one at a time as L<getopt(3)> does, mutually exclusive options (i.e., B<-F>,
B<-f>, and B<-q>) that are given on the command line cannot be resolved by
seeing which comes last. Instead, a set of built-in precedences is used: B<-q>
overrides B<-f>, which overrides B<-F>.
This program is implemented as a L<perl(1)> script, which means that non-ARPA
members on SDF cannot run it. An attempt was made to convert it to a shell
script, but problems were encountered in dealing with wildcards in operands.
Wildcard matching is implemented using Perl's C<glob> function, which may or
may not support whatever non-standard patterns you desire.
=head1 SEE ALSO
L<command(1)>, L<whereis(1)>, L<which(1)>
=head1 AUTHOR
John T. Wodder II <
[email protected]>
=head1 LICENSE
Feel free to do whatever the Tartarus you want with this.
=head1 HISTORY
B<finbin> was originally written 15 Oct 2008 by John T. Wodder II. It was last
edited 14 Dec 2008 by John Wodder.
=cut