IFS='
'
#另一种常见的安全性攻击,则是欺骗软件,它执行非我们所预期的命令。为了阻断
#这种攻击,我们希望调用的程序是可信任的版本,而非潜伏在用户提供的查找路径
#下的欺骗程序,因此我们将PATH设最小值,存储初始值供以后使用。exprot语句
#是这里的关键么,它可以确保所有子进程继承我们的安全查找路径。
OLDPATH="$PATH"
PATH=/bin:/usr/bin
export PATH
#错误输出函数
error(){
echo "$@" 1>&2
usage_and_exit 1
}
#简短的一个信息提示函数,$PROGRAM稍后会赋值为命令名
usage(){
echo "Usage: $PROGRAM [--all] [--?] [--help] [--version] envvar pattern(s)"
}
#提供信息和状态码退出
usage_and_exit(){
usage
exit $1
}
#提供用户版本号
version(){
echo "$PROGRAM version $VERSION"
}
#给出警告信息并在状态码上加1,记录警告次数
warning(){
echo "$@" 1>&2
EXITCODE=`expr $EXITCODE + 1`
}
#按大写全局,小写局部命名规则,初始化需要用的变量
all=no
envvar=
EXITCODE=0
#basename会截去参数最后一个斜杠之前字串,返回剩下的部分
PROGRAM=`basename $0`
VERSION=1.0
#接下来这块就是linux经典的命令行参数解析部分了,不多解释,需要注意的是?号
#是通配符,所以筛选选项的时候防止展开加上单引号。
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 "Unrecognized option: $1"
* )
break
#这里我小纠结了一下esac命令,没搞清楚在这干嘛的,也没这个命令说明,仔细看
#看才发现是case逆序写法,是case的结束标志,就像if结束标志fi一样
esac
shift
done
#下面我们要处理除选项外的参数了,我们可以用"$@"来取得,但是避免将他们存
#储在变量内如files="$@",因为文件名中如果有空格将无法正确被处理。
envvar="$1"
test $# -gt 0 && shift
#因为有可能用户提供的环境变量是PATH,为安全性考虑会重设,这是我们检测该变
#量,并适当更新envvar,开头的x是为了避免开展当成test的选项。
test "x$envvar" = "xPATH" && envvar=OLDPATH
#下边这句虽然很段,但是最棘手部分:使用shell的eval语句。我们envvar里已经拥
#有了环境变量的名称,可以"$envvar"取得,但我们现在要的是它的展开,我们也
#想要冒号分隔符转换成一般空白分隔符。如果MYPATH为用户所提供的名称,我们










