如何使用systemd在启动时运行Linux程序
是否需要在启动时启动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"不要在下次重启时启动该服务。
如果要停止服务并阻止其在启动时启动,请同时使用这两个命令。