Allow specifying a match in program output.
[profile.git] / opt / bin / find_working
1 #!/bin/bash
2 #
3 # find_working: Find a version of some tool in the PATH which actually runs.
4 # Usage: find_working [options] <prog>
5 # Options: -A          Don't test arguments to executable files.
6 #          -a <args>   Use arguments to test executable files.  Default --help.
7 #          -g <re>     Search string in <args> output.  Default <prog>.
8 #          -q          Don't print path to prog.  Just exit 0 if found.
9 #          -x          Don't try to execute unreadable files.  Assume success.
10 #          -X          Don't try to execute unreadable files.  Assume failure.
11 #
12
13 args="-h -? --help"
14 quiet=0
15 unreadable=
16 re=
17 while getopts ":Aa:g:qxX" opt; do
18   case $opt in
19     A) args="";;
20     a) args="$OPTARG";;
21     g) re="$OPTARG";;
22     q) quiet=1;;
23     x) unreadable=0;;
24     X) unreadable=1;;
25   esac
26 done
27 shift $((OPTIND-1))
28
29 prog="$1"; shift
30 if [ -z "$prog" ]; then
31   echo >&2 "Usage: find_working [options] <prog>"
32   echo >&2 "Options: -A          Don't test arguments to executable files."
33   echo >&2 "         -a <args>   Use arguments to test executable files.  Default --help."
34   echo >&2 "         -g <re>     Search string in <args> output.  Default <prog>."
35   echo >&2 "         -q          Don't print path to prog.  Just exit 0 if found."
36   echo >&2 "         -x          Don't try to execute unreadable files.  Assume success."
37   echo >&2 "         -X          Don't try to execute unreadable files.  Assume failure."
38   exit 1
39 fi
40
41 [ -z "$re" ] && re="\\b$prog\\b"
42
43 # Default args contain -? which might be interpreted as a glob.
44 set -o noglob
45
46 ret=
47 for path in ${PATH//:/ }; do
48   [ -x "$path/$prog" ] || continue
49
50   if [ -r "$path/$prog" ]; then
51     if [ -n "$args" ]; then
52       "$path/$prog" $args 2>&1 | grep "$re" >/dev/null || continue
53     else
54       ldd "$path/$prog" 2>/dev/null | grep "not found" >/dev/null && continue
55     fi
56     ret="$path/$prog"
57     break
58   elif [ -z "$unreadable" ]; then
59     "$path/$prog" $args 2>&1 | grep "$re" >/dev/null || continue
60     ret="$path/$prog"
61     break
62   elif [ $unreadable = 0 ]; then
63     ret="$path/$prog"
64     break
65   elif [ $unreadable = 1 ]; then
66     continue
67   fi
68
69   exit 0
70 done
71
72 if [ -n "$ret" ]; then
73   [ $quiet = 0 ] && echo "$ret"
74   exit 0
75 fi
76
77 exit 100