路径查找
时间:2010-05-19 来源:zyd_cu
#!/bin/bash
#
#在查找路径下寻找一个或多个原始文件或文件模式
#查找路径由一个指定的环境变量指定
#
#标准输出产生结果,所有的匹配结果或是第一个匹配结果
#或是filename:not found的标准错误输出
#
#如果所有文件都找到,则退出码为0
#否则即为找不到文件的个数
#shell的退出码限制为125
#
#语法:
# pathfind [--all] [--?] [--help] [--version] envvar pattern(s)
#选项--all指的是寻找路径名下的所有目录,而不是找到一个就停止
#
#
#为防止shell脚本IFS攻击(在命令行改变IFS的值,影响shell对输入的解释),在脚本#的开始将IFS设置为换行符,空格以及制表符
IFS='
'
#为防止欺骗性软件攻击(即在命令行设置PATH的路径,使得shell执行的命令并非我们所#预期的命令),将PATH设置为一个最小值
OLDPATH="$PATH"
PATH=/bin:/usr/bin
export PATH
#打印错误信息,并退出,echo打印的信息被定向到标准出错输出
error()
{
echo "$@" 1>&2
usage_and_exit 1
}
#打印pathfind用法提示信息
usage()
{
echo "Usage: $PROGRAM [--all] [--?] [--help] [--version] envvar pattern(s)"
}
#打印用法信息并退出
usage_and_exit()
{
usage
exit $1
}
#打印程序版本信息
version()
{
echo "$PROGRAM version $VERSION"
}
#当没有找到某一pattern时,打印警告消息,并增加EXITCODE的值
warning()
{
echo "$@" 1>&2
EXITCODE=`expr $EXITCODE + 1`
}
#小写的变量为本地函数或程序使用,而大写变量则被整个程序全局性的共享
all=no
envvar=
EXITCODE=0
PROGRAM=`basename $0`
VERSION=1.0
#参数分析
while test $# -gt 0
do
case $1 in
--all | --al | --a | -all | -al | -a ) #模糊匹配
all=yes
;;
--help | --hel | --he | --h | '--?' | -help | -hel | -he | -h | '-?' )
usage_and_exit 0
;;
--version | --versio | --versi | --vers | --ver | --ve | --v | \
-version | -versio | --versi | -vers | -ver | -ve | -v )
version
exit 0
;;
-* )
error "Unrecongnized option: $1"
;;
* )
break
;;
esac
shift
done
#分析完剩下envvar以及patterns参数
envvar="$1"
test $# -gt 0 && shift
#用户设置的envvar为PATH
test "x$envvar" = "xPATH" && envvar=OLDPATH
#将查找路径中的:替换为空格
dirpath=`eval echo '${'"$envvar"'}' 2>/dev/null | tr : ' '`
#检查参数有效性
if test -z "$envvar"
then
error Environment variable missing or empty
elif test "x$dirpath" = "x$envvar"
then
error "Broken sh on this platform: cannot expand $envvar"
elif test -z "$dirpath"
then
error Empty directory search path
elif test $# -eq 0
then
exit 0
fi
#剩下的参数为多个pattern
#针对每一个pattern,在每一个查找路径中查找
for pattern in "$@"
do
result=
for dir in $dirpath
do
for file in $dir/$pattern
do
if test -f "$file"
then
result="$file"
echo $result
test "$all" = "no" && break 2
fi
done
done
test -z "$result" && warning "$pattern: not found"
done
#限制退出状态值
test $EXITCODE -gt 125 && EXITCODE=125
exit $EXITCODE