killproc函数
killproc函数的作用是根据给定程序名杀进程。中间它会获取程序名对应的pid号,且保证/proc目录下没有pid对应的目录才表示进程关闭成功。
- # A function to stop a program.
- killproc() {
- local RC killlevel= base pid pid_file= delay try
-
- RC=0; delay=3; try=0
- # Test syntax.
- if [ "$#" -eq 0 ]; then
- echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
- return 1
- fi
- if [ "$1" = "-p" ]; then # 指定pid_file。不给"-p"时,"__pids_var_run"将检查/var/run下的文件
- pid_file=$2
- shift 2
- fi
- if [ "$1" = "-d" ]; then # awk的多目运算符。delay的有效值单位为d(天)、时(h)、分(m)、秒(s)。
- # 不写单位时默认为秒。该语句将所给时间转换成秒,接受小数,做四舍五入计算
- delay=$(echo $2 | awk -v RS=' ' -v IGNORECASE=1 '{if($1!~/^[0-9.]+[smhd]?$/) exit 1;d=$1~/s$|^[0-9.]*$/?1:$1~/m$/?60:$1~/h$/?60*60:$1~/d$/?24*60*60:-1;if(d==-1) exit 1;delay+=d*$1} END {printf("%d",delay+0.5)}')
- if [ "$?" -eq 1 ]; then
- echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]
- return 1
- fi
- shift 2
- fi
-
- # check for second arg to be kill level
- [ -n "${2:-}" ] && killlevel=$2 # 获取稍后的kill程序将要发送的信号
-
- # Save basename.
- base=${1##*/}
-
- # Find pid. # 获取program的pid号,以让kill程序杀掉
- __pids_var_run "$1" "$pid_file" # 检查program是否已有对应pid文件,并返回pidfile中所有pid值
- RC=$?
- if [ -z "$pid" ]; then
- if [ -z "$pid_file" ]; then
- pid="$(__pids_pidof "$1")" # pid为空,且没有pidfile时,获取program的pid
- else
- [ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
- fi
- fi
-
- # Kill it. # 根据pid,杀掉已存在的进程
- if [ -n "$pid" ] ; then # 如果进程pid存在,则杀死它
- [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
- if [ -z "$killlevel" ] ; then # 没有指定要传递的信号时
- if checkpid $pid 2>&1; then # 给定pid在/proc目录中是否有对应目录
- # TERM first, then KILL if not dead
- kill -TERM $pid >/dev/null 2>&1 # 先发送TERM信号
- usleep 50000
- if checkpid $pid ; then # 0.5秒后还没死透,则
- try=0
- while [ $try -lt $delay ] ; do # 在给定delay时间内不断检测是否已死
- checkpid $pid || break
- sleep 1
- let try+=1
- done
- if checkpid $pid ; then # 超出delay后,发送KILL信号强制杀死
- kill -KILL $pid >/dev/null 2>&1
- usleep 50000
- fi
- fi
- fi
- checkpid $pid # 若/proc下还有pid对应的目录,则进程关闭失败
- RC=$?
- [ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
- RC=$((! $RC))
- # use specified level only
- else # 使用指定的信号杀进程
- if checkpid $pid; then
- kill $killlevel $pid >/dev/null 2>&1
- RC=$?
- [ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
- elif [ -n "${LSB:-}" ]; then
- RC=7 # Program is not running
- fi
- fi
- else # 如果进程pid不存在,表示未运行
- if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
- RC=7 # Program is not running
- else
- failure $"$base shutdown"
- RC=0
- fi
- fi
-
- # Remove pid file if any.
- if [ -z "$killlevel" ]; then # 未给定信号时,可能KILL信号强杀时使得pid文件还存在,手动移除它
- rm -f "${pid_file:-/var/run/$base.pid}"
- fi
- return $RC
- }
复制代码
根据此脚本,可以知道关闭进程时,需要再三确定pid文件是否存在,/proc下是否有和pid对应的目录。直到/proc下已经没有了和pid对应的目录时,才表示进程真正杀死了。但此时pid文件仍可能存在,因此还要保证pid文件已被移除。
该函数的调用方法:
killproc [-p pidfile] [ -d delay] {program} [-signal]
|