LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 199|回复: 0

killproc函数

[复制链接]
发表于 2023-12-19 16:20:40 | 显示全部楼层 |阅读模式

killproc函数
killproc函数的作用是根据给定程序名杀进程。中间它会获取程序名对应的pid号,且保证/proc目录下没有pid对应的目录才表示进程关闭成功。

  1. # A function to stop a program.
  2. killproc() {
  3.     local RC killlevel= base pid pid_file= delay try
  4.    
  5.     RC=0; delay=3; try=0
  6.     # Test syntax.
  7.     if [ "$#" -eq 0 ]; then
  8.         echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]"
  9.         return 1
  10.     fi
  11.     if [ "$1" = "-p" ]; then  # 指定pid_file。不给"-p"时,"__pids_var_run"将检查/var/run下的文件
  12.         pid_file=$2
  13.         shift 2
  14.     fi
  15.     if [ "$1" = "-d" ]; then  # awk的多目运算符。delay的有效值单位为d(天)、时(h)、分(m)、秒(s)。
  16.                               # 不写单位时默认为秒。该语句将所给时间转换成秒,接受小数,做四舍五入计算
  17.         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)}')
  18.         if [ "$?" -eq 1 ]; then
  19.             echo $"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]
  20.             return 1
  21.         fi
  22.         shift 2
  23.     fi
  24.    
  25.     # check for second arg to be kill level
  26.     [ -n "${2:-}" ] && killlevel=​$2     # 获取稍后的kill程序将要发送的信号
  27.    
  28.     # Save basename.
  29.     base=${1##*/}
  30.    
  31.     # Find pid.                       # 获取program的pid号,以让kill程序杀掉
  32.     __pids_var_run "$1" "$pid_file"   # 检查program是否已有对应pid文件,并返回pidfile中所有pid值
  33.     RC=$?
  34.     if [ -z "$pid" ]; then
  35.         if [ -z "$pid_file" ]; then
  36.             pid="$(__pids_pidof "$1")"  # pid为空,且没有pidfile时,获取program的pid
  37.         else
  38.             [ "$RC" = "4" ] && { failure $"$base shutdown" ; return $RC ;}
  39.         fi
  40.     fi
  41.    
  42.     # Kill it.    # 根据pid,杀掉已存在的进程
  43.     if [ -n "$pid" ] ; then    # 如果进程pid存在,则杀死它
  44.         [ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] && echo -n "$base "
  45.         if [ -z "$killlevel" ] ; then       # 没有指定要传递的信号时
  46.             if checkpid $pid 2>&1; then  # 给定pid在/proc目录中是否有对应目录
  47.                 # TERM first, then KILL if not dead
  48.                 kill -TERM $pid >/dev/null 2>&1   # 先发送TERM信号
  49.                 usleep 50000
  50.                 if checkpid $pid ; then           # 0.5秒后还没死透,则
  51.                     try=0
  52.                     while [ $try -lt $delay ] ; do   # 在给定delay时间内不断检测是否已死
  53.                         checkpid $pid || break
  54.                         sleep 1
  55.                         let try+=1
  56.                     done
  57.                     if checkpid $pid ; then          # 超出delay后,发送KILL信号强制杀死
  58.                         kill -KILL $pid >/dev/null 2>&1
  59.                         usleep 50000
  60.                     fi
  61.                 fi
  62.             fi
  63.             checkpid $pid   # 若/proc下还有pid对应的目录,则进程关闭失败
  64.             RC=$?
  65.             [ "$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base shutdown"
  66.             RC=$((! $RC))
  67.         # use specified level only
  68.         else                            # 使用指定的信号杀进程
  69.             if checkpid $pid; then
  70.                 kill $killlevel $pid >/dev/null 2>&1
  71.                 RC=$?
  72.                 [ "$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base $killlevel"
  73.             elif [ -n "${LSB:-}" ]; then
  74.                 RC=7 # Program is not running
  75.             fi
  76.         fi
  77.     else                              # 如果进程pid不存在,表示未运行
  78.         if [ -n "${LSB:-}" -a -n "$killlevel" ]; then
  79.             RC=7 # Program is not running
  80.         else
  81.             failure $"$base shutdown"
  82.             RC=0
  83.         fi
  84.     fi
  85.    
  86.     # Remove pid file if any.
  87.     if [ -z "$killlevel" ]; then    # 未给定信号时,可能KILL信号强杀时使得pid文件还存在,手动移除它
  88.             rm -f "${pid_file:-/var/run/$base.pid}"
  89.     fi
  90.     return $RC
  91. }
复制代码

根据此脚本,可以知道关闭进程时,需要再三确定pid文件是否存在,/proc下是否有和pid对应的目录。直到/proc下已经没有了和pid对应的目录时,才表示进程真正杀死了。但此时pid文件仍可能存在,因此还要保证pid文件已被移除。

该函数的调用方法:

killproc [-p pidfile] [ -d delay] {program} [-signal]
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表