systemctl和服务命令之间的区别


143

systemd为我们提供了systemctl命令套件,主要用于使服务在引导时启动。我们还可以借助来启动,停止,重新加载,重新启动和检查服务状态systemctl

我们能做到的,例如sudo systemctl enable service_name,并且service_name会在开机时自动启动。我们还可以禁用在启动时无法启动的服务。

servicesystemctl命令之间唯一systemctl可用于在运行时启用服务启动的区别吗?我们可以systemctl在任何服务上使用吗?还有哪些其他显着差异?


我想您自己选错了答案。
埃文·卡罗尔

Answers:


144

service命令是包装器脚本,它使系统管理员可以启动,停止和检查服务状态,而不必担心实际使用的初始化系统。在介绍systemd之前,它是/etc/init.d脚本和Upstart initctl命令的包装,而现在是这两个以及 它们的包装systemctl

使用消息来源,卢克!

它检查Upstart:

# Operate against system upstart, not session
unset UPSTART_SESSION
if [ -r "/etc/init/${SERVICE}.conf" ] && which initctl >/dev/null \
   && initctl version 2>/dev/null | grep -q upstart \
   && initctl status ${SERVICE} 2>/dev/null 1>/dev/null
then
   # Upstart configuration exists for this job and we're running on upstart

如果那不起作用,它将查找systemd:

if [ -d /run/systemd/system ]; then
   is_systemd=1
fi

...

# When this machine is running systemd, standard service calls are turned into
# systemctl calls.
if [ -n "$is_systemd" ]
then

如果同样失败,它会退回到System V /etc/init.d脚本中:

run_via_sysvinit() {
   # Otherwise, use the traditional sysvinit
   if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
      exec env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" ${ACTION} ${OPTIONS}
   else
      echo "${SERVICE}: unrecognized service" >&2
      exit 1
   fi
}

...
run_via_sysvinit

由于该service命令是一个非常简单的包装程序,因此与实际的初始化系统可能提供的内容相比,它仅支持有限的操作子集。

为了在Ubuntu的各种版本上具有可移植性,用户可以可靠地使用该service命令来启动,停止,重新启动或检查服务的状态。但是,对于更复杂的任务,实际使用的命令是initctlsystemctl/etc/init.d可能必须直接使用脚本。

此外,作为包装器,service脚本在某些情况下还比直接等效命令所能做的更多。例如:

  • 它总是/etc/init.d在干净的环境中执行脚本。(请注意上面函数中的 env命令调用run_via_sysvinit。)
  • restart在Upstart系统上映射到stop/ 的组合start,因为initctl restart如果该服务尚未运行,则平原将出错。
  • 当停止具有相关套接字的systemd服务时,它将停止套接字:

    case "${ACTION}" in
      restart|status)
         exec systemctl $sctl_args ${ACTION} ${UNIT}
      ;;
      start|stop)
         # Follow the principle of least surprise for SysV people:
         # When running "service foo stop" and foo happens to be a service that
         # has one or more .socket files, we also stop the .socket units.
         # Users who need more control will use systemctl directly.

Upstart服务直接在服务配置文件中启用(或通过覆盖禁用),并且System V脚本通过update-rc.d命令(在/etc/rc*目录中管理符号链接)service启用或禁用,因此该命令从不参与启动时启用或禁用服务。


34
  • systemd与SysV向后兼容。
  • 在启动时并行加载服务
  • 提供按需激活服务
  • 它是基于依赖的
  • 还有更多我想...

除了您提到的功能之外,还有很多其他systemctl功能。

systemd 与单元一起使用时,单元的类型不同:目标,服务,套接字等。目标与运行级别的概念相同,它们是一堆单元。

您可以systemctl用来设置或获取默认系统目标。

systemctl get-default

您可以进入其他目标:

systemctl isolate multiuser.target

其他目标是:多用户,图形,reue,紧急,重启,关机。

如您所说,您可以systemctl用来管理服务,我知道一些与服务管理相关的其他命令:

# Restarts a service only if it is running.
systemctl try-restart name.service

# Reloads configuration if it's possible.
systemctl reload name.service

# try to reload but if it's not possible restarts the service
systemctl reload-or-restart name.service

您可以使用它来了解服务状态:

systemctl status name.service

systemctl is-active name.service # running
systemctl is-enabled name.service # will be activated when booting
systemctl is-failed name.service # failed to load

您可以屏蔽或取消屏蔽服务:

systemctl mask name.service
systemctl unmask name.service

如果您屏蔽了将要链接到的服务,则/dev/null手动或自动其他服务将无法激活/启用该服务。(您应该先将其屏蔽)。

systemctl的另一种用法是列出单位:

systemctl list-units

其中列出了所有类型的单位,已加载并处于活动状态。

列出服务单位:

systemctl list-units --type=service

或列出所有可用单元,而不仅仅是已加载和激活的单元:

systemctl list-unit-files

您可以创建别名,甚至可以控制远程计算机

systemctl --host ravexina@192.168.56.4 list-units

另一方面service,它要做的是管理服务,与其他人的业务无关;)


1
那是一个完美的答案,有什么service可以做但不能做的systemctl吗?
luv.preet

我没有意识到这一点,我认为看看服务手册页会有所帮助。
Ravexina '17

1
有几个明显的区别。语法是一种。据我所知,另一个是systemv脚本从未处理过套接字。systemd试图处理网络类型的东西这一事实是另一个事实,这是经常批评的地方。总而言之,systemd不仅在尝试提供服务,还尝试做更多的事情
Sergiy Kolodyazhnyy

我想在这里抱怨systemd隐藏来自失败service start尝试的日志消息。预先系统化后,service start会让我立即看到为什么我的服务无法启动。后系统化后,我必须先查看四个或五个不同的日志,然后才能找到它。说了这么多,我的评论无疑是不合时宜的,可能会被删除。
Ross Presser

11
AFAICS这个答案似乎并没有说明任何有关service命令的内容,这不是问题的一部分吗?
ilkkachu
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.