linux命令service xxx start是如何工作的

今天测试环境mysql停掉了,按经验执行了service mysql start,脚本报错mysql:unrecognized service,之前一直用service这个命令,控制服务的启动停止,查看服务状态。需要研究下它是怎么执行的,man一下:

service runs a System V init script in as predictable environment as possible, removing most environment variables and with current working directory set to /.
The SCRIPT parameter specifies a System V init script, located in /etc/init.d/SCRIPT. The supported values of COMMAND depend on the invoked script, service passes COMMAND and OPTIONS it to the init script unmodified. All scripts should support at least the start and stop commands. As a special case, if COMMAND is –full-restart, the script is run twice, first with the stop command, then with the start command.
service –status-all runs all init scripts, in alphabetical order, with the status command.

service命令是Redhat Linux兼容的发行版中用来控制系统服务的实用工具,它以启动、停止、重新启动和关闭系统服务,还可以显示所有系统服务的当前状态,在CentOS下,service命令的路径是/sbin/service

#!/bin/sh

. /etc/init.d/functions

VERSION="$(basename $0) ver. 0.91"
USAGE="Usage: $(basename $0) < option > | --status-all | \
[ service_name [ command | --full-restart ] ]"
SERVICE=
SERVICEDIR="/etc/init.d"
OPTIONS=

if [ $# -eq 0 ]; then
   echo "${USAGE}" >&2
   exit 1
fi

cd /
while [ $# -gt 0 ]; do
  case "${1}" in
    --help | -h | --h* )
       echo "${USAGE}" >&2
       exit 0
       ;;
    --version | -V )
       echo "${VERSION}" >&2
       exit 0
       ;;
    *)
       if [ -z "${SERVICE}" -a $# -eq 1 -a "${1}" = "--status-all" ]; then
          cd ${SERVICEDIR}
          for SERVICE in * ; do
            case "${SERVICE}" in
              functions | halt | killall | single| linuxconf| kudzu)
                  ;;
              *)
                if ! is_ignored_file "${SERVICE}" \
            && [ -x "${SERVICEDIR}/${SERVICE}" ]; then
                  env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" status
                fi
                ;;
            esac
          done
          exit 0
       elif [ $# -eq 2 -a "${2}" = "--full-restart" ]; then
          SERVICE="${1}"
          if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
            env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" stop
            env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" start
            exit $?
          fi
       elif [ -z "${SERVICE}" ]; then
         SERVICE="${1}"
       else
         OPTIONS="${OPTIONS} ${1}"
       fi
       shift
       ;;
   esac
done

if [ -f "${SERVICEDIR}/${SERVICE}" ]; then
   env -i PATH="$PATH" TERM="$TERM" "${SERVICEDIR}/${SERVICE}" ${OPTIONS}
else
   echo $"${SERVICE}: unrecognized service" >&2
   exit 1
fi

service命令真正执行的脚本放在/etc/init.d/这个目录下,可以看到,这个目录下放置了很多常用服务的控制脚本,grep一下mysql,发现原来机器上脚本的文件名是mysql.server,修改命令service mysql.server start,解决。

扩展一下

/etc/init.d/是啥?有什么用?什么时候执行?

linux启动过程

  1. The BIOS or a bootloader (lilo, zlilo, grub, etc) loads Linux Kernel from disk to memory, with some parameters defined in the bootloader configuration. We can see this process watching the dots that appear in the screen. Kernel file stays in the /boot directory, and is accessed only at this moment.
  2. In memory, Kernel code starts to run, detecting a series of vital devices, disk partitions etc.
  3. On of the last things Kernel does is to mount the / (root) filesystem, that obrigatoriamente must contain the /etc, /sbin, /bin and /lib directories.
  4. Immediately behind, calls the program called init (/sbin/init) and passes the control to him.
  5. The init command will read his configuration file (/etc/inittab) which defines the system runlevel, and some Shell scripts to be run.
  6. These scripts will continue the setup of system’s minimal infrastructure, mounting other filesystems (according to /etc/fstab), activating swap space (virtual memory), etc.
  7. The last step, and most interesting for you, is the execution of the special script called /etc/rc.d/rc, which initializes the subsystems according to a directory structure under /etc/rc.d. The name rc comes from run commands.

重点关注init的执行过程,内核加载完成后,启动的第一个进程是/sbin/init,在此过程中,会读取/etc/inittab,确定运行级别,Linux允许为不同的场合,分配不同的开机启动程序,这就叫做”运行级别”(runlevel)。也就是说,启动时根据”运行级别”,确定要运行哪些程序。运行级别如下:
0. 系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
1. 单用户工作状态,root权限,用于系统维护,禁止远程登陆
2. 多用户状态(没有NFS)
3. 完全的多用户状态(有NFS),登陆后进入控制台命令行模式
4. 系统未使用,保留
5. X11控制台,登陆后进入图形GUI模式
6. 系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动

我们的后台服务器运行级别是3,也就是会以3为参数,运行/etc/rc.d/rc,去执行/etc/rc.d/rc3.d/目录下的所有的rc启动脚本,/etc/rc.d/rc3.d/目录中的这些启动脚本实际上都是一些连接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。
/etc/rc.d/rc3.d/下的链接文件都是以“S/K+数字+方法名”命名的,对于以S开头的启动脚本,将以start参数来运行,如果以K开头,则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。
系统根据runlevel启动完rcX.d中的脚本之后,会调用rc.local脚本,如果你有一个脚本命令不论在3和5都想开机启动,那么就添加与此,免去rc3.drc5.d分别增加启动脚本工作量.
init执行完成所有的脚本后,就可以建立终端,用户登录了。

参考

http://www.runoob.com/linux/linux-system-boot.html
https://www.ibm.com/developerworks/cn/linux/l-linuxboot/index.html
https://www.ibm.com/developerworks/cn/linux/kernel/startup/index.html
https://www.zhihu.com/question/20126189

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值