#!/bin/sh
# This script finds executable files on a Unix system by
# searching four sources of information:
# (i) the user's PATH environment variable,
# (ii) the 'whereis' command,
# (iii) a path supplied as a parameter and
# (iv) the 'locate' command (if available).
#
# The result is a (space separated) list of directories where the
# executable can be found.
# Please note that the returned list of directories is not
# necessarily in the same order of directories found in the user's
# PATH environment variable. (This was done on purpose to reduce
# disk i/o, see below.)
# The primary advantage with this script is that the can collate
# search results from the various search tools provided by Unix.
# The second advantage with this script is that duplicate paths
# are removed before accessing the disk, thereby reducing disk i/o.
#
# Example invocation:
# findfile tclsh /local/tcl-7.5/bin:/roo/tcl-7.5/bin
# Here 'tclsh' is the executable file that we want to find and
# the second parameter is a colon-separated path of extra directories
# to search.
#
# Possible improvements:
# 1) use 'which' to check for aliases
# 2) use 'find' to search a hierarchy
# 3) include help page
#
# Author: Graham Phillips
# Date created: 1996
# Last modified: September 1999
findfile () {
# A function to search for executable files.
# Argument 1: executable file that we want to find
# Argument 2: extra directories (not in PATH) to search
# Example
# findfile tclsh /local/tcl-7.5/bin:/roo/tcl-7.5/bin
fname=$1
if [ "$fname" = "" ] ; then
exit
fi
found=0
other_dirs=$2
# First use `whereis`.
# Append results to f_list.
# All our list contains entries separated by spaces.
list=`whereis -b $fname 2>/dev/null`
ff_list=`echo $list | sed 's/..*:[ ]*\(.*\)/\1/g'`
f_list=""
if [ "$ff_list" != "" ] ; then
for i in $ff_list ; do
f_list="$f_list "`echo $i | sed 's/\(..*\)\/[^\/][^\/]*/\1/g'`
done
fi
# Next, try `locate`, which is typically found on FreeBSD systems.
# This step can be time-consuming.
paths=`which locate 2> /dev/null`
l_list=""
if test -x $paths 2> /dev/null; then
l_list=`locate $fname 2> /dev/null`
for i in $l_list ; do
# check if the name after the last '/' is $fname
# strip everything up to the last '/'
j=`echo $i | sed 's/.*\///g'`
if [ "$j" = "$fname" ]; then
l_list="$l_list $j"
fi
done
fi
# Next, use PATH environment variable and parameter passed in.
# Append results to u_list.
paths="$f_list $l_list"`echo $PATH:$other_dirs | sed 's/\(:\)/ /g'`
u_list=""
for i in $paths ; do
# remove trailing / in dir
j=`echo $i | sed 's/\/$//g'`
u_list="$u_list $j"
done
# Next, sort and remove duplicates.
# Results put in e_list.
s_list=`echo $u_list | tr ' ' '\012' | sort | uniq`
e_list=""
for i in $s_list ; do
if test -x ${i}/$fname ; then
e_list="$e_list $i"
fi
done
if [ "$e_list" != "" ] ; then
echo $e_list
fi
}
findfile $*
exit
               (
geocities.com/grahamgrebe)