本文以tomcat7为例。大家都知道tomcat的启动从bin/startup.sh开始,那我就顺着这条线往下挖吧。首先是判断所处的系统:
os400=false
darwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
OS400*) os400=true;;
Darwin*) darwin=true;;
esac
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh
$0代表命令或执行脚本本身,在这里就是startup.sh,由于这个脚本可能被软链接到其他地方,所以在while循环中做了一个解析,以确定本尊所在的目录。
test表达式的-h选项表示“存在且是一个软链接”,所以只要结果为true就会循环执行中间的代码。ls的-ld选项可以显示出软链接真正的指向,如下:
m@sys:~$ ls -ld startup.sh
lrwxrwxrwx 1 m m 31 12月 18 10:22 startup.sh -> programs/tomcat7/bin/startup.sh
但是我们只需要箭头后面打部分,所以用expr命令截取。截取之后做一个判断:若是以“/”开头表示是绝对目录,于是直接将其赋值给PRG;否则就是相对目录,那么dirname "$PRG"的值必然是“.”,即当前软链接所在的目录,然后PRG的值就是“./programs/tomcat7/bin/startup.sh”。
从而PRGDIR的值就是“./programs/tomcat7/bin”
接着就该判断该目录下是否存在catalina.sh脚本了,有的话就直接执行:
if $os400; then
# -x will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
eval
else
if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
echo "Cannot find $PRGDIR/$EXECUTABLE"
echo "This file is needed to run this program"
exit 1
fi
fi
exec "$PRGDIR"/"$EXECUTABLE" start "$@"
如果是os400系统就执行eval命令,我查了一下linux似乎没有这个命令,应该是os400系统的,所以我们直接看else部分。test表达式的-x选项表示文件存在且有可执行权限,所以$PRGDIR"/"$EXECUTABLE不满足这个选项时,直接报错退出;否则就可以执行最后一条命令了。
最后我们看看catalina.sh是如何被启动的:它是被exec命令启动的,且传入了两个参数,一个是start,这个参数意义很明显;那么第二个是啥意思?搜了一下,它也是一个shell内置变量,功能和“$*”类似,都代表传递给命令或脚本的所有参数,只是前者以数组的形式存储,而“$*”以字符串的形式存储。在这里的作用是把所有传递给startup.sh的变量全部给catalina.sh。
os400=false
darwin=false
case "`uname`" in
CYGWIN*) cygwin=true;;
OS400*) os400=true;;
Darwin*) darwin=true;;
esac
然后时定位catalina.sh脚本的位置:
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`/"$link"
fi
done
PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh
$0代表命令或执行脚本本身,在这里就是startup.sh,由于这个脚本可能被软链接到其他地方,所以在while循环中做了一个解析,以确定本尊所在的目录。
test表达式的-h选项表示“存在且是一个软链接”,所以只要结果为true就会循环执行中间的代码。ls的-ld选项可以显示出软链接真正的指向,如下:
m@sys:~$ ls -ld startup.sh
lrwxrwxrwx 1 m m 31 12月 18 10:22 startup.sh -> programs/tomcat7/bin/startup.sh
但是我们只需要箭头后面打部分,所以用expr命令截取。截取之后做一个判断:若是以“/”开头表示是绝对目录,于是直接将其赋值给PRG;否则就是相对目录,那么dirname "$PRG"的值必然是“.”,即当前软链接所在的目录,然后PRG的值就是“./programs/tomcat7/bin/startup.sh”。
从而PRGDIR的值就是“./programs/tomcat7/bin”
接着就该判断该目录下是否存在catalina.sh脚本了,有的话就直接执行:
if $os400; then
# -x will Only work on the os400 if the files are:
# 1. owned by the user
# 2. owned by the PRIMARY group of the user
# this will not work if the user belongs in secondary groups
eval
else
if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
echo "Cannot find $PRGDIR/$EXECUTABLE"
echo "This file is needed to run this program"
exit 1
fi
fi
exec "$PRGDIR"/"$EXECUTABLE" start "$@"
如果是os400系统就执行eval命令,我查了一下linux似乎没有这个命令,应该是os400系统的,所以我们直接看else部分。test表达式的-x选项表示文件存在且有可执行权限,所以$PRGDIR"/"$EXECUTABLE不满足这个选项时,直接报错退出;否则就可以执行最后一条命令了。
最后我们看看catalina.sh是如何被启动的:它是被exec命令启动的,且传入了两个参数,一个是start,这个参数意义很明显;那么第二个是啥意思?搜了一下,它也是一个shell内置变量,功能和“$*”类似,都代表传递给命令或脚本的所有参数,只是前者以数组的形式存储,而“$*”以字符串的形式存储。在这里的作用是把所有传递给startup.sh的变量全部给catalina.sh。