转自:https://www.cnblogs.com/image-eye/archive/2011/10/26/2220405.html

functions这个脚本是给/etc/init.d里边的文件使用的。提供了一些基础的功能,看看里边究竟有些什么。首先会设置umask,path,还有语言环境,然后会设置success,failure,warning,normal几种情况下的字体颜色。下面再看看提供的重要方法:
checkpid:检查是否已存在pid,如果有一个存在,返回0(通过查看/proc目录)
daemon:启动某个服务。/etc/init.d目录部分脚本的start使用到这个
killproc:杀死某个进程。/etc/init.d目录部分脚本的stop使用到这个
pidfileofproc:寻找某个进程的pid
pidofproc:类似上面的,只是还查找了pidof命令
status:返回一个服务的状态
echo_success,echo_failure,echo_passed,echo_warning分别输出各类信息
success,failure,passed,warning分别记录日志并调用相应的方法
action:打印某个信息并执行给定的命令,它会根据命令执行的结果来调用 success,failure方法
strstr:判断$1是否含有$2
confirm:显示 "Start service $1 (Y)es/(N)o/(C)ontinue? [Y]"的提示信息,并返回选择结果
详细分析:
# -*-Shell-script-*-
#
# functions This file contains functions to be used by most or all            # 注释 :该脚本几乎被 /etc/init.d/ 下的所有脚本所调用,因为它包含了大量的
#  shell
scripts in the /etc/init.d
directory.                                           # 的基础函数。同时也被
/etc/rc.d/rc.sysinit ,例如 success、action、failure 等函数
#

TEXTDOMAIN=initscripts                # 设置 TEXTDOMAIN 变量

#某些系统使用LC_MESSAGES shell变量所指定的消息类型. 其他一些系统根据
shell变量TEXTDOMAIN的值来创建消息类型的名称, 可能还会加上后缀'.mo'. 如果
你使用TEXTDOMAIN变量, 你可能需要设置变量TEXTDOMAINDIR指向消息类型文件所
在的位置. 还有某些系统以这种形式两个变量都使用: TEXTDOMAINDIR/LC_MESSAGES
/Lc_Messages/TEXTDOMAIN.mo.
########################################################################################################################
# Make sure umask is sane            # 确保 root 用户的 umask 是正确的 022 (也就是 rwxr-xr-x)
umask 022

# Set up a default search path.                                        # 设置默认的 PATH 变量
PATH="/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin"         # 默认为 /sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
export PATH                                                                  # 导出为环境变量

# Get a sane screen width                                                # 设置正确的屏幕宽度
[ -z "${COLUMNS:-}" ] && COLUMNS=80                                # 如果 COLUMNS 变量的值为空,则设置为 80 (列)

[
-z "${CONSOLETYPE:-}" ] &&
CONSOLETYPE="`/sbin/consoletype`"            # 如果 CONSOLETYPE 为空则设置
CONSOLETYPE 为 /sbin/consoletype 命令返回的值
                                                                                                            
# 一般是 vt 或者 pty 、serial
#######################################################################################################

if [ -f /etc/sysconfig/i18n -a -z
"${NOLOCALE:-}" ] ; then                           # 如果存在
/etc/sysconfig/i18n 且 NOLOCALE 变量的值为空,则
      .
/etc/sysconfig/i18n                                                                                        #
执行 /etc/sysconfig/i18n 文件,取得 LANG 变量的值
      if [ "$CONSOLETYPE" !=
"pty" ];
then                                                                    #
如果当前 console 类型不是 pty(远程登录),而是 vt 或者 serial ,则
          case
"${LANG:-}"
in                                                                                                    #
根据 LANG 的值作出选择
              ja_JP*|ko_KR*|zh_CN*|zh_TW*|bn_*|bd_*|pa_*|hi_*|ta_*|gu_*)                                        #
如果 LANG 是 日文、中文简体、中文繁体、韩文等,则
                   export
LC_MESSAGES=en_US                                                                                                #
把 LC_MESSAGES 设置为 en_US
                   export
LANG                                                                                                                       #
同时导出为环境变量
                   ;;
              *)
                  
export
LANG                                                                                                               #
如果是其他类型的语言,则直接导出 LANG
               ;    ;
         esac
      else                                                                                                                    #
如果当前 consle 是 pty                                                    
      
[ -n "$LC_MESSAGES" ] && export
LC_MESSAGES                                                       # 且如果
LC_MESSAGES 不为空,则直接导出 LC_MESSAGES 
       export LANG
  fi
fi

#######################*******************************###################

case语句 :它能够把变量的内容与多个模板进行匹配,再根据成功匹配的模板去决定应该执行哪部分代码。
  使用格式:
  case 匹配母板 in
    模板1 [ | 模板2 ] … )  语句组 ;;
    模板3 [ | 模板4 ] … )  语句组 ;;
  esac
  case语句的匹配是从上往下地匹配顺序。因此,case语句编写的原则是从上往下,模板从特殊到普通。在C语言里,case语句中有default模板,而在shell程序设计中,可能将模板写成*,就可以完成相同的功能。

case语句的模板支持匹配
  匹配以n开头的所有情况: n*
  匹配yes的所有字母大小不同的情况: [yY][eE][sS]
  但不支持{}匹配,因为模板可以使用 | 就可以达到目的。

例程:

#!/bin/sh

echo "Please input \"yes\" or \"no\""

read var

case "$var" in

[yY][eE][sS] ) echo "Your input is YES" ;;

[nN][oO]     ) echo "Your input is YES" ;;

*            ) echo "Input Error!"      ;;

esac

exit 0

#############*******************#################

###########################################################################################################

# 下面是设置 success、failure、passed、warning 4种情况下的字体颜色的

# Read in our configuration
if [ -z "${BOOTUP:-}" ]; then                                                # 首先如果 BOOTUP 变量为空,则
  if
[ -f /etc/sysconfig/init ];
then                                            # 如果存在
/etc/sysconfig/init 文件,执行 /etc/sysconfig/init 文件
      . /etc/sysconfig/init
  else                                                                                    # 否则我们就手工设置
    # This all seem confusing? Look in /etc/sysconfig/init,
    # or in /usr/doc/initscripts-*/sysconfig.txt
    BOOTUP=color                                                                       # 第一设置 BOOTUP 变量,默认就是 color 
    RES_COL=60                                                                           # 第二设置设置在屏幕的第几列输出后面的 "[ xxx ]" ,默认是第60列
    MOVE_TO_COL="echo
-en \\033[${RES_COL}G"                           # MOVE_TO_COL 是用于打印
"OK" 或者 "FAILED" ,或者 "PASSED" ,或者 "WARNING" 之前的部分,不含 "[" 
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"                             # SETCOLOR_SUCCESS 设置后面的字体都为绿色
    SETCOLOR_FAILURE="echo -en \\033[1;31m"                              # SETCOLOR_FAILURE 设置后面将要输出的字体都为红色
    SETCOLOR_WARNING="echo -en \\033[1;33m"                            # SETCOLOR_WARNING 设置后面将要输出的字体都为黄色
    SETCOLOR_NORMAL="echo -en \\033[0;39m"                              # SETCOLOR_NORMAL 设置后面输出的字体都为白色(默认)
    LOGLEVEL=1
  fi

if [ "$CONSOLETYPE" = "serial" ]; then                                        # 如果是通过串口登录的,则全部取消彩色输出
      BOOTUP=serial
      MOVE_TO_COL=
      SETCOLOR_SUCCESS=
      SETCOLOR_FAILURE=
      SETCOLOR_WARNING=
      SETCOLOR_NORMAL=
  fi
fi

##########################################################################################################################################################
if [ "${BOOTUP:-}" != "verbose" ]; then                    # 如果 BOOTUP 变量的值不为 verbose ,则
   INITLOG_ARGS="-q"                                                    # 把 INITLOG_ARGS 的值设置为 -q (安静模式)
else                                                                     # 否则
   INITLOG_ARGS=                                                         # 把 INITLOG_ARGS 的值请空 
fi
#################################################################################################
# Check if $pid (could be plural) are running            # 下面定义一个函数 checkpid (),目的是检查 /proc 下是否存在指定的目录(例如 /proc/1/)
checkpid() {                                                         # 如果有任意一个存在,则返回0;
local i   #局部变量定义

for i in $* ; do
  [ -d "/proc/$i" ] && return 0
done
return 1                                                             # 如果给出的参数全部不存在对应的目录,则返回1
}

#####################################################################################################
#
A function to start a program.                            #
下面定义最重要的一个函数,daemon 函数,它的作用是启动某项服务。/etc/init.d/ 下的脚本的 start 部分都会用到它
daemon() {
# Test syntax.
local gotbase= force=
local base= user= nice= bg= pid=
nicelevel=0
while
[ "$1" != "${1##[-+]}" ]; do                                        #
daemon 函数本身可以指定多个选项,例如 --check <value> ,--check=<value> ,
   case $1 in
     '')    echo $"$0: Usage: daemon [+/-nicelevel] {program}"    # 也可以指定 nice 值
            return 1;;
     --check)
     base=$2
     gotbase="yes"
     shift 2
     ;;
     --check=?*)
         base=${1#--check=}
     gotbase="yes"
     shift
     ;;

--user)                                                                        #
也可以指定要以什么用户身份运行(--user <usr> , --user=<usr>)
     user=$2
     shift 2
     ;;
     --user=?*)
            user=${1#--user=}
     shift
     ;;
     --force)
         force="force"                                                           # --force 表示强制运行
     shift
     ;;
     [-+][0-9]*)
         nice="nice -n $1"                                                        # 如果 daemon 的第一个参数是数字,则认为是 nice 值
            shift
     ;;
     *)     echo $"$0: Usage: daemon [+/-nicelevel] {program}"
            return 1;;
   esac
done

# Save basename.                                                        # basename 就是从服务器的二进制程序的 full path 中取出最后的部分
        [ -z "$gotbase" ] && base=${1##*/}

# See if it's already running. Look *only* at the pid file.    # 检查该服务是否已经在运行。不过 daemon 函数只查看 pid 文件而已
if [ -f /var/run/${base}.pid ]; then                                         # 如果 /var/run 下存在该服务的 pid 文件,则
  local line p
  read
line <
/var/run/${base}.pid                                               # 从该
pid 文件每次读取一行,送给变量 line 。注意 pid 文件可能有多行,且不一定都是数字
  for p in $line ; do                                                                   # 对于 line 变量的每个 word 进行检查
  
[ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid
$p"                     # 如果 p 全部是数字,且存在 /proc/$p/ 目录,则认为该数字是一个 pid
,把它加入到 pid 变量
  done                                                                                       # 到最后 pid 变量的值可能是有多个由空格分隔的数字组成
fi

[ -n "${pid:-}" -a -z "${force:-}" ] && return                                  # 如果 pid 变量最终为空,则 force 变量为空(不强制启动),则返回

# make sure it doesn't core dump anywhere unless requested        # 下面对该服务使用的资源作一些设置
ulimit
-S -c ${DAEMON_COREFILE_LIMIT:-0} >/dev/null 2>&1         #
ulimit 是控制由该 shell 启动的进程能够使用的资源,-S 是 soft control 的意思,-c 是指最大的 core   
                                                                                                #
dump 文件大小,如果 DEAMON_COREFILE_LIMIT 为空,则默认为 0

# if they set NICELEVEL in /etc/sysconfig/foo, honor
it                # 如果存在 /etc/sysconfi/foo 文件,且其中有 NICELEVEL
变量则用它代替  daemon 后面的那个 nice 值
[ -n "$NICELEVEL" ] &&
nice="nice -n $NICELEVEL"                        # 注意,这里的 nice 赋值是用 nice
-n <value> 的格式,因为 nice 本身可以启动命令,用这个格式较方便

# Echo daemon                                                                         # 如果 BOOTUP 的值为 verbose ,则打印一个服务名
        [ "${BOOTUP:-}" = "verbose" -a -z "$LSB" ] && echo -n " $base"

# And start it up.                                                                                       # 下面是开始启动它了
if
[ -z "$user" ];
then                                                                                  #
如果 user 变量为空,则默认使用 root 启动它
    $nice initlog $INITLOG_ARGS -c
"$*"                                                                # 执行
nice -n <nice_value> initlog -q -c "$*" 
else                                                                                                         # 如果指定了用户,则
    $nice
initlog $INITLOG_ARGS -c "runuser -s /bin/bash - $user -c
\"$*\""                # 执行 nice -n <nice_value> initlog -q -c
"runuser -s /bin/bash - <user> -c "$*"
fi
[ "$?" -eq 0 ]
&& success $"$base startup" || failure $"$base
startup"                # 如果上面的命令成功,则显示一个绿色的 [ OK ] ,否则显示 [ FAILURE ]
}

################################################################################################ 
# A function to stop a program.                                # 下面定义另外一个很重要的函数 killproc ,/etc/init.d/ 下面的脚本的 stop 部分都会用到它
killproc() {
RC=0                                                                    # RC 是最终返回的值,初始化为 0
# Test syntax.
if
[ "$#" -eq 0 ]; then                                            #
killproc 函数的语法格式是 killproc <service> [<signal>] ,例如 killproc
sm-client 9
  echo $"Usage: killproc {program} [signal]"              
  return 1
fi

notset=0                                                             # noset 是用于检查用户是否指定了 kill 要使用的信号
# check for second arg to be kill level                  
if [ -n "$2" ]; then                                                # 如果 $2 不为空,则表示用户有设定信号,则
  killlevel=$2                                                            # 把 $2 的值赋予 killlevel 变量
else                                                                    # 否则
  notset=1                                                                # notset 变量的值为1,同时 killlevel 为 '-9' (KILL 信号)
  killlevel="-9"
fi

# 补充 :注意,并不是说用户没有指定信号地停止某项服务时,就会立即用 kill -9 这样的方式强制杀死,而是先用 TERM 信号,然后再用 KILL

# Save basename.
        base=${1##*/}                                                # basename 就是得出服务的名称

# Find pid.
pid=                                                                    # 把 pid 变量的值清空。注意,不是指 pid 变量的值等于下面脚本的执行结果,要看清楚
if [ -f /var/run/${base}.pid ]; then                         # 下面和上面的 daemon 函数一样找出 pid 
    local line p
    read line < /var/run/${base}.pid
    for p in $line ; do
       [ -z "${p//[0-9]/}" -a -d "/proc/$p" ] && pid="$pid $p"
    done
fi
if [ -z "$pid" ]; then                                                # 不过和 daemon 不同的是,一旦 pid 为空不会直接 return 而是尝试用 pid 命令再次查找
  pid=`pidof -o $$ -o $PPID -o %PPID -x $1 || \            # -o 是用于忽略某个 pid ,-o $$ 是忽略当前 shell 的 pid、-o $PPID 是忽略 shell 的 pid 
   pidof -o $$ -o $PPID -o %PPID -x $base`                   # -o %PPID 是忽略 pidof 命令的父进程,要查询的进程是 $1 (fullpath) 或者 $base 
fi

# Kill it.                                                            
  if [ -n "${pid:-}" ] ; then                                        # 如果 pid 的值最终不为空,则
    [ "$BOOTUP" = "verbose" -a -z "$LSB" ] && echo -n "$base "    # 且 BOOTUP 的值为 verbose ,且 LSB 变量不为空,则打印一个服务名

if [ "$notset" -eq "1" ] ; then                                        # 如果 notset 变量不为1,表示用户没有指定信号,则
         if checkpid $pid 2>&1; then                                        # 调用 checkpid  $pid 检查是否在 /proc/ 下存在进程目录,如果有
              # TERM first, then KILL if not dead                            # 先尝试用 TERM 信息,不行再用 KILL 信号
              kill -TERM $pid >/dev/null 2>&1                                # 执行 kill -TERM $pid 
              usleep 100000                                                          # usleep 和 sleep 一样,不过单位是百万分之1秒。这里休眠1秒
              if
checkpid $pid && sleep 1
&&                                # 如果 checkpid $pid 还是查到有
/proc/<pid>/ 目录存在,则表示还没有杀死,继续等待1秒
                 checkpid $pid && sleep 3 &&                                # 如果1秒后用 checkpid 检查还是有,则再等待3秒;
                 checkpid $pid ; then                                           # 如果还是没有杀死,则用 KILL 信号
                        kill -KILL $pid >/dev/null 2>&1                            # 执行 kill -KILL 杀死它
                        usleep 100000                                                    # 等待1秒种
              fi
    fi
    checkpid $pid                                                             # 再次检查 pid 目录       
    RC=$?                                                                         # 并把结果返回给 RC ,这就算是 killproc 的最后状态了
    [
"$RC" -eq 0 ] && failure $"$base shutdown" || success $"$base
shutdown"    # 如果 RC 的值为0,则表示kill -9 没有杀死了进程,则调用 failure 函数,否则调用
success 
    RC=$((! $RC))
  
    # use specified level only                                            # 上面都是在没有指定信号的情况的,下面是用户指定了信号的。例如 restart)或者 reload)部分
    else    # 这个 else 是针对 if [ "$notset" -eq "1" ]  的
       if checkpid $pid; then                                             # 如果检查到进程存在,则
            kill $killlevel $pid >/dev/null 2>&1                            # 执行kill命令,但使用指定的信号 $killlevel
            RC=$?                                                                     # 并把状态值返回给变量 RC
            [
"$RC" -eq 0 ] && success $"$base $killlevel" || failure $"$base
$killlevel"    # 如果 RC 为0则表示成功,调用 success;否则调用 failure 函数
       fi
  fi
else      # 这个 else 是针对 if [ -n "${pid:-}" ]  的,也就是说没有 pid 文件,pidof 命令也没有找到 pid ,则
     failure $"$base shutdown"                # 调用 failure 函数,表示停止服务失败
     RC=1                                             # 同时 RC 的值为1
fi

# Remove pid file if any.                    # 根据具体情况可能需要删除 pid 文件
if [ "$notset" = "1" ]; then                    # 如果 notset 不为1 ,也就是用户没有指定信号的情况
            rm -f /var/run/$base.pid            # 自动删除 /var/run 下的 pid 文件
fi
return $RC                                        # 并把 RC 作为 exit status 返回
}

# 补充 :自所以删除 pid 文件只针对 notset 为1 的情况,是因为 -HUP 信号(重读配置),并不杀死进程,所以不能删除它的 pid 文件

# 例如下面 :
# ps -ef |grep xinetd
root      2635     1  0 12:25 ?        00:00:00 xinetd -stayalive -pidfile /var/run/xinetd.pid

# ./xinetd reload
Reloading configuration:                                   [  OK  ]

# ps -ef |grep xinetd
root      2635     1  0 12:25 ?        00:00:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
root      3927  3412  0 16:43 pts/0    00:00:00 grep xinetd

#可以看到 pid 在 reload 后并没有变

##################################################################################################
# A function to find the pid of a program. Looks *only* at the pidfile

# 下面的 pidfileofproc 函数和 checkpid 类似,但不执行 pidof 命令,只查询 pid 文件
pidfileofproc() {
local base=${1##*/}

# Test syntax.
if [ "$#" = 0 ] ; then
  echo $"Usage: pidfileofproc {program}"
  return 1
fi

# First try "/var/run/*.pid" files
if [ -f /var/run/$base.pid ] ; then
         local line p pid=
    read line < /var/run/$base.pid
    for p in $line ; do
         [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p"
    done
         if [ -n "$pid" ]; then
                 echo $pid
                 return 0
         fi
fi
}
#################################################################################################
# A function to find the pid of a program.                        # 下面的 pidofproc 函数和上面的 pidfileofproc 函数类似,但多了一步 pidof 命令
pidofproc() {
base=${1##*/}

# Test syntax.
if [ "$#" = 0 ]; then
  echo $"Usage: pidofproc {program}"
  return 1
fi

# First try "/var/run/*.pid" files
if [ -f /var/run/$base.pid ]; then
         local line p pid=
  read line < /var/run/$base.pid
  for p in $line ; do
         [ -z "${p//[0-9]/}" -a -d /proc/$p ] && pid="$pid $p"
  done
         if [ -n "$pid" ]; then
                 echo $pid
                 return 0
         fi
fi
pidof -o $$ -o $PPID -o %PPID -x $1 || \
  pidof -o $$ -o $PPID -o %PPID -x $base
}
####################################################################################
status() {                                                                  # 注释 :下面的 status 函数是判断服务的状态,总共有4种
local base=${1##*/}
local pid

# Test syntax.
if [ "$#" = 0 ] ; then
  echo $"Usage: status {program}"
  return 1
fi

# First try "pidof"                                                        # 同样是查找 pid 先。直接使用 pidof 命令
pid=`pidof -o $$ -o $PPID -o %PPID -x $1 || \                
      pidof -o $$ -o $PPID -o %PPID -x ${base}`
if [ -n "$pid" ]; then                                                    # 如果 pid 变量的值不为空,则表示找到进程,
         echo $"${base} (pid $pid) is running..."                 # 则打印 "xxx (pid nnn) is running " ,
         return 0                                                             # 并返回 0
fi

# Next try "/var/run/*.pid" files                                    # 如果 pidof 命令没有找到,则尝试从 pid 文件找
if [ -f /var/run/${base}.pid ] ; then
         read pid < /var/run/${base}.pid
         if [ -n "$pid" ]; then                                                # 如果 pidof 命令找不到,但从 pid 文件找到了 pid ,则
                 echo $"${base} dead but pid file exists"                # 打印 "xxx dead but pid file exists",
                 return 1                                                             # 并返回 1
         fi
fi
# See if /var/lock/subsys/${base} exists                            # 如果 pidof 命令和 pid 文件都没有找到 pid ,则
if [ -f /var/lock/subsys/${base} ]; then                              # 如果在 /var/lock/subsys 下存在对应的文件,则
  echo $"${base} dead but subsys locked"                               # 打印 “xxxx dead but subsys locked”,
  return 2                                                                            # 并返回 2
fi
echo
$"${base} is stopped"                                                #
如果 pidof 命令、pidf 文件都没有找到pid ,且没有别锁,则打印 “xxx is stopped”
return 3                                                                           # 并返回3
}
###########################################################################################

# 注释 :下面的 echo_xxx 函数就是真正在屏幕上打印 [ ok ] 、[ PASSED ]、[ FAILURE ]、[ WARNING ] 的部分了

echo_success() {                                                                    # 下面是 echo_success 部分
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL                           # 首先是打印 “[” 之前的空格
  echo -n "[  "                                                                         # 然后打印 "[" 
  [ "$BOOTUP" = "color" ] && $SETCOLOR_SUCCESS                    # 设置字体为红色
  echo -n $"OK"                                                                       # 打印 OK
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL                     # 返回字体为白色
  echo -n "  ]"                                                                         # 打印 "]"    
  echo -ne "\r"                                                                        # 换行。
  return 0                                                                               # 返回 0,其他一律返回 1

echo_failure() {
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
  echo -n "["
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo -n $"FAILED"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo -n "]"
  echo -ne "\r"
  return 1
}

echo_passed() {
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
  echo -n "["
  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
  echo -n $"PASSED"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo -n "]"
  echo -ne "\r"
  return 1
}

echo_warning() {
  [ "$BOOTUP" = "color" ] && $MOVE_TO_COL
  echo -n "["
  [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
  echo -n $"WARNING"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo -n "]"
  echo -ne "\r"
  return 1
}
##################################################################################################
# Inform the graphical boot of our current state
update_boot_stage() {
  if [ "$GRAPHICAL" = "yes" -a -x /usr/bin/rhgb-client ]; then
    /usr/bin/rhgb-client --update="$1"
  fi
  return 0
}
################################################################################################
# Log that something succeeded                                                
success()

{                                                                                                #
success 函数除了打印 [ xxx ] 之外,还会使用 initlog 记录信息
  if [ -z "${IN_INITLOG:-}" ]; then
    
initlog $INITLOG_ARGS -n $0 -s "$1" -e
1                                                   # -n 是 --name 的意思,-s
是 --string ,-e 是 --event ,1 表示完全成功
  else
     # silly hack to avoid EPIPE killing rc.sysinit
     trap "" SIGPIPE
     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21
     trap - SIGPIPE
  fi
  [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_success
  return 0
}

# Log that something failed
failure() {
  rc=$?
  if [ -z "${IN_INITLOG:-}" ]; then
     initlog $INITLOG_ARGS -n $0 -s "$1" -e 2                                                    # failure 的话 --event 是 2 是失败
  else
     trap "" SIGPIPE
     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 2" >&21
     trap - SIGPIPE
  fi
  [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_failure
  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
  return $rc
}

# Log that something passed, but may have had errors. Useful for fsck
passed() {
  rc=$?
  if [ -z "${IN_INITLOG:-}" ]; then
     initlog $INITLOG_ARGS -n $0 -s "$1" -e 1                                                 # passed 的话 --event 还是1
  else
     trap "" SIGPIPE
     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21
     trap - SIGPIPE
  fi
  [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_passed
  return $rc
}

# Log a warning
warning() {
  rc=$?
  if [ -z "${IN_INITLOG:-}" ]; then
     initlog $INITLOG_ARGS -n $0 -s "$1" -e 1                                                # warning 的话 --event 也是 1
  else
     trap "" SIGPIPE
     echo "$INITLOG_ARGS -n $0 -s \"$1\" -e 1" >&21
     trap - SIGPIPE
  fi
  [ "$BOOTUP" != "verbose" -a -z "$LSB" ] && echo_warning
  return $rc

####################################################################################################
#
Run some action. Log its
output.                                                        # action
函数是另外一个最重要的函数,它的作用是打印某个提示信息并执行给定命令
tion() {
  STRING=$1
  echo -n "$STRING "
  if [ "${RHGB_STARTED}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
      echo -n "$STRING " > /etc/rhgb/temp/rhgb-console
  fi
  shift
  initlog $INITLOG_ARGS -c "$*" && success $"$STRING" || failure $"$STRING"
  rc=$?
  echo
  if [ "${RHGB_STARTED}" != "" -a -w /etc/rhgb/temp/rhgb-console ]; then
      if [ "$rc" = "0" ]; then
       echo_success > /etc/rhgb/temp/rhgb-console
      else
        echo_failed > /etc/rhgb/temp/rhgb-console
[ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
      fi
      echo
  fi
  return $rc
}
###############################################################################################
# returns OK if $1 contains $2                        # strstr 函数是判断 $1 字符串是否含有 $2 字符串,是则返回0,否则返回1
() {
  [ "${1#*$2*}" = "$1" ] && return 1
  return 0
}
#############################################################################################
# Confirm whether we really want to run this service                                       # confirm 函数是用于交互式的启动服务
nfirm() {
  [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=yes
  while : ; do 
    echo -n $"Start service $1 (Y)es/(N)o/(C)ontinue? [Y] "                                   # 会打印一个提示信息
    read answer
    if strstr $"yY" "$answer" || [ "$answer" = "" ] ; then                                          # 如果 answer 变量是 y 或者 Y 则
        return

0                                                                                                                #
返回 0(但未真正启动)
    elif strstr $"cC" "$answer" ;
then                                                                    #
如果 answer 是 c 或者 C ,则
        rm -f
/var/run/confirm                                                                                          #
删除 /var/run/confirm 文件                           
        [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --details=no
        return

2                                                                                                                #
返回2
   elif strstr $"nN" "$answer" ;
then                                                                      #
如果 answer 是 n 或者 N,则
  return
1                                                                                                                       #
直接返回1
     fi
  done
}

(转)/etc/init.d/functions详解的更多相关文章

  1. Linux学习之/etc/init.d/functions详解

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=28773997&id=3996557 /etc/init.d/f ...

  2. Android的init过程详解(一)(转)

    本文使用的软件版本 Android:4.2.2 Linux内核:3.1.10 本文及后续几篇文章将对Android的初始化(init)过程进行详细地.剥丝抽茧式地分析,并且在其中穿插了大量的知识,希望 ...

  3. Linux init详解(转)

    Linux init详解 一.什么是INIT: init是Linux系统操作中不可缺少的程序之一. 所谓的init进程,它是一个由内核启动的用户级进程. 内核自行启动(已经被载入内存,开始运行,并已初 ...

  4. Android的init过程详解(一)

    Android的init过程详解(一) Android的init过程(二):初始化语言(init.rc)解析 本文使用的软件版本 Android:4.2.2 Linux内核:3.1.10 本文及后续几 ...

  5. Linux 启动详解之init

    1.init初探 init是Linux系统操作中不可缺少的程序之一.init进程,它是一个由内核启动的用户级进程,然后由它来启动后面的任务,包括多用户环境,网络等. 内核会在过去曾使用过init的几个 ...

  6. init命令详解

    基础命令学习目录首页 1.手动输入命令会执行相关操作   #init 0 - 停机(千万不能把initdefault 设置为0 )   #init 1 - 单用户模式   #init 2 - 多用户, ...

  7. Linux init 详解(0,1,2,3,4,5,6)

    一.什么是 init init是Linux系统操作中不可缺少的程序之一. 所谓的init进程,它是一个由内核启动的用户级进程. 内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数 ...

  8. [转]keil使用详解

    第一节 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上.结构性.可读性.可维护性上有明显的优势,因而易学易用.用过 ...

  9. Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解

    转载:http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

随机推荐

  1. 安卓开发_浅谈主配置文件(AndroidManifest.xml)

    AndroidManifest.xml本质:是整个应用的主配置清单文件包含:该应用的包名,版本号,组件,权限等信息作用:记录该应用的相关的配置信息 一.常用标签(1).全局篇(包名,版本信息)(2). ...

  2. B-树、B+树

    B-树 用来在外部存储中组织数据. 严格来说,2-3树.2-3-4树都是B-树的特例:但B树更强调它的节点有很多个子节点,B-树中的节点可以有几十或几百个子节点. B-树也可以是查找树,也可以不是查找 ...

  3. vue-cli快速原型开发

    我们知道vue-cli提供了一套如何快速搭建vue开发脚手架的工具,虽然好用,但是有的时候我们还是嫌麻烦,因为就想快速开发调试一个组件,这时我们就可以使用vue-cli 3.x以上版本的一个好特性: ...

  4. Python & 机器学习之项目实践

    机器学习是一项经验技能,经验越多越好.在项目建立的过程中,实践是掌握机器学习的最佳手段.在实践过程中,通过实际操作加深对分类和回归问题的每一个步骤的理解,达到学习机器学习的目的. 预测模型项目模板不能 ...

  5. 关于无限试用JetBrains产品的方案

    JetBrains免费试用期限为30天,通过对其试用机制的设想,找到了其破解试用机制的方案,具体如下: 在选择试用JetBrains产品的时候,它会在 C:\Users\用户名\对应产品\config ...

  6. 彻底卸载删除Win10易升,禁止再生

    易升是微软推出的win10升级工具.用户可通过易升一键升级win10. 因为我的电脑已经是win10的系统,所以我也不需要升级.也不想升级,因为我从网上了解到升级后的系统反而没有升级前的好用. 微软的 ...

  7. httpd的一些知识点

    一.httpd持久化连接:使用httpd之telnet测试其keepalive连接状态 作用:连接建立后,每个资源获取结束不会断开连接,而继续等待其他资源请求并完成传输. 1.KeepAlive  O ...

  8. 2018. first week now at home

    外面雪刚停. 现在是2018.1.5 2018 needs to consider next steps了.未雨绸缪啊     下面是2017年last working day   外面黑了,水面上黑 ...

  9. Python getting started guide

    Get up in the morning. The first thing is to write a blog, although it uses machine translation, it ...

  10. Treiber Stack介绍

    简介 Treiber Stack在 R. Kent Treiber在1986年的论文Systems Programming: Coping with Parallelism中首次出现.它是一种无锁并发 ...