在日常使用 CentOS 的时候,systemd 应该是最常用的一个进程管理工具了。但是,我发现我和别人的使用方式不太一样,我见到很多人都是喜欢使用 systemctl 命令,但是,我却是经常使用的 service 命令,于是我就想知道为什么两种方式都可以,他们有什么区别,但是却一直没有动手。

最近,我遇到了一个新的情况,那就是我用 service 的时候,发现出来的命令提示和平时的不太一样,只有 start.stoprestart 选项,然后认真看了一下发现居然是 init.d 目录下的,所以这个时候是机会看一下 service 命令了。

查了一下发现,原来 service 是一个 shell 脚本,然后位置在:/sbin/service,内容就不全贴了,在我的环境下,大概的内容是这样的:

  1. [root@liqiang.io]# cat /sbin/service
  2. ...
  3. if [ -f "${SERVICEDIR}/${SERVICE}" ]; then
  4. # LSB daemons that dies abnormally in systemd looks alive in systemd's eyes due to RemainAfterExit=yes
  5. # lets reap them before next start
  6. if [ "${ACTION}" = "start" ] && \
  7. systemctl show -p ActiveState ${SERVICE}.service | grep -q '=active$' && \
  8. systemctl show -p SubState ${SERVICE}.service | grep -q '=exited$' ; then
  9. /bin/systemctl stop ${SERVICE}.service
  10. fi
  11. env -i PATH="$PATH" TERM="$TERM" SYSTEMCTL_IGNORE_DEPENDENCIES=${SYSTEMCTL_IGNORE_DEPENDENCIES} SYSTEMCTL_SKIP_REDIRECT=${SYSTEMCTL_SKIP_REDIRECT} "${SERVICEDIR}/${SERVICE}" ${ACTION} ${OPTIONS}
  12. elif [ -x "${ACTIONDIR}/${SERVICE}/${ACTION}" -a -n "${ACTION}" ]; then
  13. env -i PATH="$PATH" TERM="$TERM" SYSTEMCTL_IGNORE_DEPENDENCIES=${SYSTEMCTL_IGNORE_DEPENDENCIES} SYSTEMCTL_SKIP_REDIRECT=${SYSTEMCTL_SKIP_REDIRECT} "${ACTIONDIR}/${SERVICE}/${ACTION}" ${OPTIONS}
  14. elif `echo $ACTION | egrep -qw "start|stop|restart|try-restart|reload|force-reload|status|condrestart"` ; then
  15. SERVICE_MANGLED=$(/usr/bin/systemd-escape --mangle ${SERVICE})
  16. echo $"Redirecting to /bin/systemctl ${ACTION}${OPTIONS:+ }${OPTIONS} ${SERVICE_MANGLED}" >&2
  17. exec /bin/systemctl ${ACTION} ${OPTIONS} ${SERVICE_MANGLED}
  18. else
  19. echo $"The service command supports only basic LSB actions (start, stop, restart, try-restart, reload, force-reload, status). For other actions, please try to use systemctl." >&2
  20. exit 2
  21. fi

这里有一段的 if 判断,分别代表着 service 命令的查找顺序:

  1. 最开始是从 /etc/init.d 目录找 service 名字,如果有就执行,没有就继续
  2. /usr/libexec/initscripts/legacy-actions 找对应的服务操作
  3. 我日常最常使用的 systemctl 管理
  4. 报错了

就这么简单,以后使用的时候就心里更有底了。

Thanks