1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# 该函数的作用是关闭进程的.
# 用法:
# killproc [-p pidfile] [-d delay] <program> [-signal]
# -p:  指定进程的pid文件,一般在/var/run/xxx.pid
# -d:  指定延迟多长时间就强度关闭进程
# -signal: 关闭进程的信号
# A function to stop a program.             
killproc() {
        
local 
RC killlevel= base pid pid_file= delay     
        
# 定义局部变量,只在函数体内有效。
        
RC=0; delay=3  
# 默认延迟3秒,不能正常关闭就强制关闭
        
# Test syntax. # 判断用户调用该函数时,给的参数格式。并使用变量记录下来
        
if 
"$#" 
-
eq 
0 ]; 
then
                
echo 
$"Usage: killproc [-p pidfile] [ -d delay] {program} [-signal]“
        
# 如果调用该函数时,不使用任何参数的话将给用户输出使用该函数的使用方法。                                                                         
                
return 
1       
# 退出该函数。
        
fi
        
if 
"$1" 
"-p" 
]; 
then   
                
# 如果参数1,是字符 -p 的话,那么用户输入的第二个参数就是:
                
# 程序的pid_file文件。通常是/var/run/XXX.pid
                
pid_file=$2    
                
shift 
2         
        
fi
        
if 
"$1" 
"-d" 
]; 
then
                
delay=$2    
                
# 记录的参数的作用是用来。如果进程在正常情况下不能关闭,
                
# 延迟多长时间就向该进程发送SIGKILL信号强制关闭。
                
shift 
2
        
fi
        
# check for second arg to be kill level 
        
# 检查用户是否指定函数关闭进程时,所使用的信号。
        
[ -n 
"${2:-}" 
] && killlevel=$2
        
# Save basename.       # 保存进程的二进制运行文件的。
        
base=${1
##*/}          # 参数替换,把程序的二进制文件的路径名***掉。
####################################################################
        
# 查找可运行二进制程序的进程号PID 部分
        
# Find pid.
        
__pids_var_run 
"$1" 
"$pid_file"     
        
#调用 函数:__pids_var_run 来检查用户指定的程序的进程号。
        
# 该函数会使用一个变量:PID记录程序的进程号的。
        
if 
[ -z 
"$pid_file" 
-a -z 
"$pid" 
]; 
then 
        
# 如果pidfile文件不存在,并且找不到进程的pid号。
        
# 就使用该方法查找该程序$base的PID号。
                
pid=
"$(__pids_pidof "
$1
")"
        
fi
 
#####################################################################
        
# Kill it.       
        
# 找到二进制可运行程序的进程号,是如果关闭进程的
        
if 
[ -n 
"$pid" 
] ; 
then 
                       
# 如果$PID 不为空,证明进程运行的。就执行 then 后的内容
                
"$BOOTUP" 
"verbose" 
-a -z 
"${LSB:-}" 
] && 
echo 
-n 
"$base "
                
if 
[ -z 
"$killlevel" 
] ; 
then  
               
#如果用户没有指定函数要使用关闭进程的信号的话,就执行 then后的内容
                       
if 
checkpid $pid 2>&1; 
then  
                        
# 调用函数:checkpid 来判断进程号为:$PID的进程是否
                        
#运行。其实 checkpid是判断$PID,如果伪目录/proc 
                        
#下是否有一个目录名和$PID相同
                           
# TERM first, then KILL if not dead
                           
kill 
-TERM $pid >
/dev/null 
2>&1   
                           
# 给进程$PID发送 -15信号。等待进程关闭资源后,
                           
# 再杀死该进程。
                           
usleep 100000   
#等待100000 微秒
                           
if 
checkpid $pid && 
sleep 
1 && 
                               
#再使用函数checkpid检查,如果进程还运行的话,
                               
#再等待1秒,
                              
checkpid $pid && 
sleep 
$delay &&  
                              
#再使用函数checkpid检查,如果进程还运行的话,
                              
#就使用用户给的延迟时间,再等待
                              
checkpid $pid ; 
then      
                                
#在用户给的延时时间到了,再次使用函数
                                
#checkpid检查,如果进程还是运行的
                                
# 话,就强制关闭。
                                
kill 
-KILL $pid >
/dev/null 
2>&1  
                                
# 给进程$PID发送 -9 信号,强制关闭该进程。
                                
usleep 100000
                           
fi
                        
fi
                        
checkpid $pid  
# 再次确认下,进程$PID是否是关闭的。
                        
RC=$?     
                           
# 记录函数checkpid的返回结果。
                           
# 如果是:0 的话就代表关闭进程$PID成功。
                        
"$RC" 
-
eq 
0 ] && failure $
"$base shutdown" 
|| success   $
"$base shutdown"
              
# 判断函数checkpid的返回值,给用户输出进程是否关闭成功的信                        RC=$((! $RC))  
                   
# 对变量RC进行,非操作,避免下面使用该变量时,判断有误。
                
# use specified level only
                  
#调用函数:killproc时传递有关闭进程的信号就执行else 后的程序
                
else   
# 如果用户给函数killproc 传递了关闭进程所使用的信号,
                       
#就执行else后的代码
            
# 作用想要通知进程重读配置文件时, 可以传递一个 -HUP 信号给进程。
                        
if 
checkpid $pid; 
then                                                  
#使用函数checkpid检查,进程$PID是否运行的,
 
                       
kill 
$killlevel $pid >
/dev/null 
2>&1    
                             
#使用用户传递关闭进程的信号来关闭进程$PID
                                
RC=$?  
#记录函数checkpid的返回结果。 
                                
"$RC" 
eq 
0 ] && success $
"$base $killlevel"  
|| failure $
"$base $killlevel"    
                             
# 根据$RC判断进程$PID是否关闭成功                                                
                      
elif 
[ -n 
"${LSB:-}" 
]; 
then   
                                
RC=7 
# Program is not running
                        
fi
                
fi
                 
###########################找不到二进制可运行程序的进程号
        
else
                
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
            
rm 
-f 
"${pid_file:-/var/run/$base.pid}"
        
fi
        
return 
$RC
}