1#! /bin/bash 2# 3# original from: 4# @(#) where.ksh 1.1 94/07/11 5# 91/01/12 john h. dubois iii (john@armory.com) 6# 92/08/10 Only print executable *files*. 7# 92/10/06 Print err msg if no match found. 8# 92/11/27 Added implicit * 9# 93/07/23 Print help only if -h is given. 10# 94/01/01 Added -x option 11# 94/07/11 Don't bother with eval 12# 13# conversion to bash v2 syntax done by Chet Ramey 14 15name=${0##*/} 16Usage="Usage: $name [-hx] 'pattern' ..." 17typeset -i exact=0 18 19phelp() 20{ 21echo "$name: find executable files in PATH that match patterns. 22$Usage 23$name searches each directory specified in the PATH environment variable 24for executable files that match the specified patterns. Patterns are 25given as Korn shell filename patterns. They are surrounded by implicit 26'*' characters, so that \"foo\" will match any executble file whose name 27contains contains \"foo\". This can be overridden by using '^' and '$' to 28force a match to start at the beginning and end at the end of a filename 29respectively. Characters that are special to the shell must generally 30be protected from the shell by surrounding them with quotes. 31Examples: 32$name foo 33lists all executable files in PATH that contain foo. 34$name '^b*sh$' 35lists all executable files in PATH that start with b and end with sh. 36An error message is printed if a no matching file is found for a pattern. 37Options: 38-h: Print this help. 39-x: Find exact matches only; equivalent to putting ^ and $ at the start 40 and end of each pattern." 41} 42 43istrue() 44{ 45 test 0 -ne "$1" 46} 47 48isfalse() 49{ 50 test 0 -eq "$1" 51} 52 53while getopts "xh" opt; do 54 case "$opt" in 55 x) exact=1;; 56 h) phelp ; exit 0;; 57 *) echo -e "$Usage\nUse -h for help." 1>&2; exit 2;; 58 esac 59done 60 61shift $((OPTIND-1)) 62 63set +f # make sure filename globbing is on 64Args=("$@") # save args 65 66OIFS=$IFS 67IFS=: # Make PATH be split on : 68Paths=($PATH) 69IFS=$OIFS 70 71for arg in "${Args[@]}"; do 72 73 # get rid of leading ^ 74 if istrue $exact; then 75 arg=${arg} 76 else 77 case "$arg" in 78 ^*) arg=${arg#?};; 79 *) arg="*$arg" ;; # Pattern is not anchored at start 80 esac 81 fi 82 83 # get rid of trailing $ 84 if istrue $exact; then 85 arg="$arg" 86 else 87 case "$arg" in 88 *\$) arg=${arg%?} ;; 89 *) arg="$arg*" ;; 90 esac 91 fi 92 93 found=0 # Pattern not found yet 94 Patterns= 95 # Make a pattern for each element of PATH 96 for PathElem in "${Paths[@]}"; do 97 [ -z "$PathElem" ] && PathElem=. 98 Patterns="$Patterns $PathElem/$arg" 99 done 100 101 # Find all pattern matches that are executable regular files. 102 for file in $Patterns; do 103 if [ -x "$file" ] && [ -f "$file" ]; then 104 echo "$file" 105 found=1 106 fi 107 done 108 if [ $found = 0 ]; then 109 echo "$arg: not found." 1>&2 110 fi 111done 112