当前位置: 首页>>技术教程>>正文


Systemctl和服务之间的区别

, , ,

问题描述

systemd为我们提供了systemctl命令,该命令主要用于使服务在启动时启动。我们还可以在systemctl的帮助下启动,停止,重新加载,重新启动和检查服务状态。

我们可以做sudo systemctl enable service_name,该服务将在启动时自动启动。我们还可以禁用不在启动时启动的服务。

servicesystemctl命令之间的唯一区别是systemctl可以在运行时启动服务吗?我们可以对任何服务使用systemctl吗?有什么其他重大差异?

最佳解决方案

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

Use the source, Luke!

它检查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命令是一个相当简单的包装器,因此与实际的init系统可能提供的操作相比,它只支持有限的操作子集。

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

此外,作为一个包装器,service脚本在某些情况下也可以执行比直接等效命令更多的操作。例如:

  • 它始终在干净的环境中执行/etc/init.d脚本。 (注意上面的run_via_sysvinit函数中的长env命令调用。)

  • 它将Upstart系统上的restart映射到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服务直接在服务配置文件中启用(或通过覆盖禁用),并且使用update-rc.d命令(在/etc/rc*目录中管理符号链接)启用或禁用System V脚本,因此service命令从未参与启用或禁用启动服务。

次佳解决方案

  • systemd向后兼容SysV。

  • 在启动时并行加载服务

  • 它提供了on-demand服务的激活

  • 它是基于依赖的

  • 还有更多我猜…

除了你提到的systemctl能够做的事情还有很多。

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

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

systemctl get-default

你可以进入其他目标:

systemctl isolate multiuser.target

其他目标是:多用户,图形,recue,紧急,重启,断电。

如您所说,您可以使用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做了它必须做的事情,管理服务并与其他人的业务无关;)

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1605.html,未经允许,请勿转载。