#!/bin/sh # find_sh4errors utility # Copyright (c) 2004 Steve Grubb. ALL RIGHTS RESERVED. # sgrubb@redhat.com # # This software may be freely redistributed under the terms of the GNU # public license. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # This script will search a directory and its subdirectories for every shell # script. It then runs sh -n to see if bash can determine if there are obvious # parsing errors. It does have a bug in that bash -n does not take into # account someone may program an unconditional exit and then include man page # generation information. It also fails to notice the exec command. When you # run across files that do either of the above, add it to the KNOWN_BAD list. if [ $# -ge 2 ] ; then echo "Usage: find_sh4errors [directory]" 1>&2 exit 1 fi INTERPRETERS="wish wishx tclsh guile rep itkwish expect /etc/kde/kdm/Xsession /etc/X11/xdm/Xsession /usr/bin/festival perl hfssh" SKIP_DIRS="/opt /home /root" KNOWN_BAD="/usr/bin/kde-build /usr/bin/cvsversion samples/copifuncs/copi.sendifm1 bashdb bash_completion_test" DIR="/" if [ $# -eq 1 ] ; then if [ -d "$1" ] ; then DIR="$1" else echo "Option passed in was not a directory" 1>&2 exit 1 fi fi tempfile=`mktemp /tmp/sh4.XXXXXX` tempfile2=`mktemp /tmp/sh4.XXXXXX` if [ -z "$tempfile" -o -z "$tempfile2" ] ; then echo ; echo "Unable to create tempfiles...aborting." 1>&2 ; echo exit 1 fi trap "rm -f $tempfile; rm -f $tempfile2; exit 2" 1 2 3 5 15 # Get executable files #echo "Locating executables..." /usr/bin/find $DIR -type f -perm /0111 -print >> $tempfile 2>/dev/null FOUND=0 #echo "Refining list to shell scripts..." while read f do # Get just the shell scripts testf=`echo $f | /usr/bin/file -n -f - | egrep 'ourne|POSIX shell'` if [ x"$testf" != x ] ; then echo $f >> $tempfile2 FOUND=1 fi done < $tempfile /bin/rm -f $tempfile if [ $FOUND -eq 0 ] ; then # Nothing to report, just exit # echo "Examining shell scripts in $DIR" # echo "No problems found" /bin/rm -f $tempfile2 exit 0 fi #echo "Examining shell scripts in $DIR" FOUND=0 while read i do # First see if the script calls an interpreter SKIP=0 for lang in $INTERPRETERS do if `/bin/cat "$i" 2>/dev/null | \ grep "exec[ \t].*$lang" >/dev/null` ; then SKIP=1 break fi done if [ $SKIP -eq 1 ] ; then continue fi # See if this is in a dir we want to ignore for d in $SKIP_DIRS do if `echo "$i" | /bin/grep "^\$d" >/dev/null`; then SKIP=1 break fi done if [ $SKIP -eq 1 ] ; then continue fi # Don't do the known naughty files for bad in $KNOWN_BAD do if `echo "$i" | /bin/grep "$bad" >/dev/null`; then SKIP=1 break fi done if [ $SKIP -eq 1 ] ; then continue fi # Now examine them for correctness interp=`/usr/bin/head -n 1 "$i" | /bin/awk '{ print $1 }' | \ /usr/bin/tr -d '#!'` if [ x"$interp" = "x" -o ! -x "$interp" ] ; then interp="/bin/sh" fi $interp -n "$i" 2>/dev/null if [ $? -ne 0 ] ; then printf "%-44s" "$i" rpm -qf --queryformat "%{NAME}-%{VERSION}" $i echo FOUND=1 fi done < $tempfile2 /bin/rm -f $tempfile2 if [ $FOUND -eq 0 ] ; then # Nothing to report, just exit # echo "No problems found" exit 0 fi exit 1