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