如何使用systemd在启动时运行Linux程序

时间:2020-01-09 10:39:38  来源:igfitidea点击:

是否需要在启动时启动Linux程序? systemd软件提供了一种在任何使用systemd的Linux发行版上执行此操作的方法,而Linux发行版在当今大多数情况下都是如此,包括Ubuntu。我们将引导我们完成创建集成服务的过程,甚至与期刊进行交流。

本教程演示了如何设置在启动系统时启动的系统服务。要在登录时启动图形程序,请改用桌面的启动管理器。

在启动时运行程序

有时,我们安装在计算机上的软件会自动挂接到Linux启动过程中,以便在每次启动计算机时自动启动该程序。我们可以使用自己的程序和脚本,或者实际上计算机上的任何其他程序,轻松实现相同的行为。

启动时启动的程序由" systemd",系统和服务管理器控制。 systemd是启动时运行的第一个进程。它总是具有进程ID(PID)1. 计算机上运行的所有其他进程都是由" systemd"启动的,或者由" systemd"已经启动的进程启动。

在后台运行的程序称为守护程序或者服务。 systemd末尾的d代表守护程序。在本文中,我们将创建一个示例服务。要勾选所有框,我们的服务必须是:

  • 通过服务单元文件与systemd集成

  • 在启动时启动

  • 可使用systemctl控制,systemd的控制界面

  • 能够写日记

创建服务程序

我们需要有一个可以启动systemd的程序。我们将创建一个简单的脚本igidea.sh。本教程使用Gedit文本编辑器,但是我们可以使用任何喜欢的文本编辑器。

touch igidea.sh
gedit igidea.sh

gedit编辑器将打开。将以下文本复制并粘贴到编辑器中。

#!/bin/bash

echo "igidea.service: ## Starting ##" | systemd-cat -p info

while :
do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "igidea.service: timestamp ${TIMESTAMP}" | systemd-cat -p info
sleep 60
done

保存更改并关闭编辑器。

该脚本并不能完成很多工作,但是有几点值得注意。

  • 两条"回声"线通过" systemd-cat"传递,该程序从程序获取输出并将其发送到日志。日记条目优先。我们使用-p(优先级)选项来表示我们的消息仅用于信息(信息)。它们不是重要的错误或者警告。

  • 有一个无限的" while"循环。

  • TIMESTAMP变量设置为当前日期和时间。这被格式化为消息并发送到日志。

  • 然后,脚本休眠60秒。

  • 60秒后,重复循环。因此,此脚本每分钟一次将带有时间戳的消息写入日志。

我们将脚本复制到/ usr / local / bin目录。

sudo cp igidea.sh /usr/local/bin

我们需要使其可执行:

sudo chmod +x /usr/local/bin/igidea.sh

创建服务单元文件

每个由" systemd"启动的程序都有一个定义文件,称为服务单元文件。它拥有" systemd"可用于定位和启动程序以及定义其某些行为的某些属性。

我们需要为我们的新服务创建一个单位文件,但是要确保没有一个现有的单位文件具有我们要提供新服务的名称,这是谨慎的做法。

sudo systemctl list-unit-files --type-service

我们可以滚动浏览按字母顺序排序的单位文件列表,并检查未使用要使用的名称。

我们的服务将称为igidea.service。没有单位文件具有该名称,因此我们可以继续创建我们的单位文件。

sudo gedit /etc/systemd/system/igidea.service

gedit编辑器将打开。将以下文本复制并粘贴到编辑器中:

[Unit]
Description=iGiftIdea Service Example

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/igidea.sh
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

保存更改并关闭编辑器。

这些条目具有这些含义。这些是典型的条目。我们简单的服务实际上并不需要它们中的大多数,但是包含它们可以让我们对其进行解释。

  • 说明:这是服务的文字说明。

  • 想要:我们的服务想要但不要求在我们的服务启动之前网络已建立。

  • 之后:成功启动此服务后应启动的单元名称列表(如果尚未运行)。

  • 类型:简单。一旦由ExecStart指定的进程被派生,systemd将认为该服务已启动。

  • ExecStart:应该启动的过程的路径。

  • 重新启动:何时以及是否应该重新启动服务。我们将其设置为失败。

  • RestartSec:尝试重新启动服务之前要等待的时间。该值以秒为单位。

  • KillMode:定义如果我们要求systemctl停止服务,systemd应该如何终止进程。我们有待处理。这导致systemd仅在主进程上使用SIGTERM信号。如果我们的服务不是一个简单的程序,而不是一个简单的脚本,那么我们将其设置为混合,以确保所有生成的进程也被终止。

  • 想要的:我们已将此设置为multi-user.target,这意味着只要系统处于多个用户可以登录的状态(无论图形用户界面是否可用),就应该启动该服务。

单位文件不需要是可执行文件,但是单位文件上的权限应该限制谁可以编辑它。我们不希望恶意或者调皮的用户更改单位文件,以使其完全执行其他程序。

此命令将授予所有者读取和写入权限,以及对该组的读取权限。其他人将没有权限。

sudo chmod 640 /etc/systemd/system/igidea.service

即使服务尚未运行,我们也可以让systemctl为我们检查单元文件的语法。任何错误将被报告。 (实际上,.service部分对于大多数命令是可选的。)

systemctl status igidea.service

没有突出显示错误,这意味着我们的单位文件在语法上是正确的。

启动服务

当我们添加一个新的单元文件或者编辑现有的文件时,必须告诉systemd重新加载单元文件定义。

sudo systemctl daemon-reload

如果要在启动时启动服务,则必须启用它:

sudo systemctl enable igidea

启用服务不会启动它,只会将其设置为在引导时启动。要立即启动服务,必须将" systemctl"与" start"方法一起使用。

sudo systemctl start igidea

验证服务

手动启动服务或者重新启动计算机后,我们可以验证我们的服务是否正常运行。

sudo systemctl status igidea.service

为我们显示服务的状态。

  • 绿点表示我们的服务正常运行。

  • 服务的名称是igidea.service,详细说明是我们在单元文件中提供的。

  • 我们显示了/etc/systemd/system/igidea.service加载了哪个单位文件。

  • 该服务处于活动状态,并且为我们列出了启动服务的时间。

  • 它的PID是7762.

  • 与服务关联的任务有两个。

  • 该服务总共使用了928 KB的内存。

  • 控制组包括igidea.sh脚本和igidea.sh启动的" sleep"命令。在大多数情况下," sleep"命令将负责该服务。

我们还显示了此服务生成的最后10个日记条目。毫不奇怪,它们之间只有一分钟的间隔。

停止和禁用服务

如果需要停止服务,可以使用以下命令停止:

sudo systemctl stop igidea.service

这将停止该服务,但不会阻止它在下次重新引导计算机时重新启动。要停止启动时启动的服务,我们需要禁用它:

sudo systemctl disable igidea.service

如果服务正在运行,则此命令不会停止它。它只是告诉" systemd"不要在下次重启时启动该服务。

如果要停止服务并阻止其在启动时启动,请同时使用这两个命令。