1#!/bin/sh 2# find_sh4errors utility 3# Copyright (c) 2004 Steve Grubb. ALL RIGHTS RESERVED. 4# sgrubb@redhat.com 5# 6# This software may be freely redistributed under the terms of the GNU 7# public license. 8# 9# You should have received a copy of the GNU General Public License 10# along with this program; if not, write to the Free Software 11# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 12 13# This script will search a directory and its subdirectories for every shell 14# script. It then runs sh -n to see if bash can determine if there are obvious 15# parsing errors. It does have a bug in that bash -n does not take into 16# account someone may program an unconditional exit and then include man page 17# generation information. It also fails to notice the exec command. When you 18# run across files that do either of the above, add it to the KNOWN_BAD list. 19 20if [ $# -ge 2 ] ; then 21 echo "Usage: find_sh4errors [directory]" 1>&2 22 exit 1 23fi 24INTERPRETERS="wish wishx tclsh guile rep itkwish expect /etc/kde/kdm/Xsession /etc/X11/xdm/Xsession /usr/bin/festival perl hfssh" 25SKIP_DIRS="/opt /home /root" 26KNOWN_BAD="/usr/bin/kde-build /usr/bin/cvsversion samples/copifuncs/copi.sendifm1 bashdb bash_completion_test" 27DIR="/" 28if [ $# -eq 1 ] ; then 29 if [ -d "$1" ] ; then 30 DIR="$1" 31 else 32 echo "Option passed in was not a directory" 1>&2 33 exit 1 34 fi 35fi 36tempfile=`mktemp /tmp/sh4.XXXXXX` 37tempfile2=`mktemp /tmp/sh4.XXXXXX` 38if [ -z "$tempfile" -o -z "$tempfile2" ] ; then 39 echo ; echo "Unable to create tempfiles...aborting." 1>&2 ; echo 40 exit 1 41fi 42trap "rm -f $tempfile; rm -f $tempfile2; exit 2" 1 2 3 5 15 43 44# Get executable files 45#echo "Locating executables..." 46/usr/bin/find $DIR -type f -perm /0111 -print >> $tempfile 2>/dev/null 47FOUND=0 48#echo "Refining list to shell scripts..." 49while read f 50do 51 # Get just the shell scripts 52 testf=`echo $f | /usr/bin/file -n -f - | egrep 'ourne|POSIX shell'` 53 if [ x"$testf" != x ] ; then 54 echo $f >> $tempfile2 55 FOUND=1 56 fi 57done < $tempfile 58/bin/rm -f $tempfile 59if [ $FOUND -eq 0 ] ; then 60 # Nothing to report, just exit 61# echo "Examining shell scripts in $DIR" 62# echo "No problems found" 63 /bin/rm -f $tempfile2 64 exit 0 65fi 66#echo "Examining shell scripts in $DIR" 67FOUND=0 68while read i 69do 70 # First see if the script calls an interpreter 71 SKIP=0 72 for lang in $INTERPRETERS 73 do 74 if `/bin/cat "$i" 2>/dev/null | \ 75 grep "exec[ \t].*$lang" >/dev/null` ; then 76 SKIP=1 77 break 78 fi 79 done 80 81 if [ $SKIP -eq 1 ] ; then 82 continue 83 fi 84 85 # See if this is in a dir we want to ignore 86 for d in $SKIP_DIRS 87 do 88 if `echo "$i" | /bin/grep "^\$d" >/dev/null`; then 89 SKIP=1 90 break 91 fi 92 done 93 94 if [ $SKIP -eq 1 ] ; then 95 continue 96 fi 97 98 # Don't do the known naughty files 99 for bad in $KNOWN_BAD 100 do 101 if `echo "$i" | /bin/grep "$bad" >/dev/null`; then 102 SKIP=1 103 break 104 fi 105 done 106 107 if [ $SKIP -eq 1 ] ; then 108 continue 109 fi 110 111 # Now examine them for correctness 112 interp=`/usr/bin/head -n 1 "$i" | /bin/awk '{ print $1 }' | \ 113 /usr/bin/tr -d '#!'` 114 if [ x"$interp" = "x" -o ! -x "$interp" ] ; then 115 interp="/bin/sh" 116 fi 117 $interp -n "$i" 2>/dev/null 118 if [ $? -ne 0 ] ; then 119 printf "%-44s" "$i" 120 rpm -qf --queryformat "%{NAME}-%{VERSION}" $i 121 echo 122 FOUND=1 123 fi 124done < $tempfile2 125/bin/rm -f $tempfile2 126if [ $FOUND -eq 0 ] ; then 127 # Nothing to report, just exit 128# echo "No problems found" 129 exit 0 130fi 131exit 1 132 133