
引言
在Linux上进行开发时,存在创建交互式脚本的任务,这些脚本在系统打开或关闭时执行。 在系统V中,这很容易完成,但是使用systemd可以进行调整。 但是它可以做它的计时器。
为什么我们需要目标
通常写为目标在系统V -init中充当运行级别的类似物。 我从根本上不同意。 其中有更多的服务,您可以将包分成几组,例如,与一个团队一起运行一组服务并执行其他操作。 此外,它们没有层次结构,只有依赖性。
启动示例(功能概述)并启动交互式脚本
目标本身的描述:
cat installer.target [Unit] Description=My installer Requires=multi-user.target Conflicts=rescue.service rescue.target After=multi-user.target rescue.service rescue.target AllowIsolate=yes Wants=installer.service
该目标将在启动multi-user.target并调用installer.service时启动。 而且,可能有几种这样的服务。
cat installer.service [Unit]
最后,是一个可执行脚本的示例:
最重要的是选择final.target-target,系统在启动时应该到达该目标。 在启动过程中,systemd将检查依赖项并运行您需要的一切。
有几种方法可以选择final.target,为此我使用了bootloader选项。
最终的发布如下:
- 引导程序启动
- 引导加载程序通过传递final.target参数来启动固件
- Systemd开始系统启动。 它从basic.target到它们的依赖项(例如multi-user.target)依次进入installer.target或work.target。 后者并导致系统以所需的模式工作
准备启动固件
创建固件时,始终需要在启动时恢复系统状态并在关闭电源时保存系统状态。 状态表示配置文件,数据库转储,接口设置等。
Systemd在一个目标中并行启动该过程。 有一些依赖关系可以让您确定脚本执行的顺序。
它如何在我的项目中工作( https://habr.com/en/post/477008/ https://github.com/skif-web/monitor )
- 系统启动
- settings_restore.service服务启动,它将检查数据部分中的settings.txt文件。 如果不存在,则将参考文件放在其位置,然后还原系统设置:
- 管理员密码
- 主机名
- 时区
- 地区
- 确定是否正在使用所有媒体。 默认情况下,图像尺寸很小-为了方便复制和录制到媒体。 启动时,检查是否还有未使用的空间。 如果存在-磁盘已重新分区。
- 从MAC地址生成计算机ID。 这对于通过DHCP获取相同的地址很重要。
- 网络设置
- 日志大小有限
- 外部驱动器已准备好工作(如果启用了相应的选项并且驱动器是新的)
- 运行postgresq
- 恢复服务启动。 需要准备zabbix本身及其数据库:
- 检查是否已经有一个zabbix数据库。 如果没有,它是通过初始化转储创建的(它们随zabbix一起提供)
- 创建时区列表(需要在Web界面中显示它们)
- 找到当前IP,它显示有问题(邀请进入控制台)
- 邀请发生变化-出现准备工作的短语
- 固件已准备就绪。
服务文件很重要,正是它们为启动设置了顺序
[Unit] Description=restore system settings Before=network.service prepare.service postgresql.service systemd-networkd.service systemd-resolved.service [Service] Type=oneshot ExecStart=/usr/bin/settings_restore.sh [Install] WantedBy=multi-user.target
如您所见,我创建了依赖项,以便首先运行脚本,然后网络将启动,DBMS将启动。
和第二项服务(准备zabbix)
这有点复杂,启动也是在multi-user.target中,但是在运行postgresql DBMS和我的setting_restore之后。 但是在运行zabbix服务之前。
带有计时器的logrotate服务
Systemd可以代替CRON。 说真的 此外,准确性不是一分钟,而是一秒(如果需要的话),并且您可以创建一个单调计时器,由事件超时调用。
这是单调的计时器,用于计数从我创建的计算机启动以来的时间。
这将需要2个文件
logrotateTimer.service-服务的实际描述:
[Unit] Description=run logrotate [Service] ExecStart=logrotate /etc/logrotate.conf TimeoutSec=300
很简单-启动命令的描述。
第二个logrotateTimer.timer文件是设置计时器工作的文件:
[Unit] Description=Run logrotate [Timer] OnBootSec=15min OnUnitActiveSec=15min [Install] WantedBy=timers.target
那里是什么:
- 计时器说明
- 第一次从系统启动开始
- 进一步发射的时期
- 计时器服务依赖性。实际上,这是使计时器工作的那条线
有关关闭和自定义关闭目标的交互式脚本
在另一个开发中,我必须通过自己的目标制作一个更复杂的关闭计算机的版本,以便执行许多操作。 通常建议使用RemainAfterExit选项创建oneshot服务,但这会阻止创建交互式脚本。
但是事实是,由ExecOnStop选项启动的命令是在TTY之外执行的! 检查很简单-插入tty命令并保存其输出。
因此,我通过目标实现了关机。 我不假装是100%正确的,但是可以!
如何完成(一般而言):
创建了目标my_shutdown.target,该目标不依赖任何人:
my_shutdown.target
[Unit] Description=my shutdown AllowIsolate=yes Wants=my_shutdown.service
当切换到该目标时(通过systemctl隔离my_shutdwn.target),他启动了my_shutdown.service服务,该服务的任务很简单-执行my_shutdown.sh脚本:
[Unit] Description=MY shutdown [Service] Type=oneshot ExecStart=/usr/bin/my_shutdown.sh StandardInput=tty TTYPath=/dev/tty3 TTYReset=yes TTYVHangup=yes WantedBy=my_shutdown.target
- 在此脚本中,我执行必要的操作。 您可以向目标添加很多脚本,以提高灵活性和便利性:
my_shutdown.sh
注意事项 使用/ tmp / reboot和/ tmp / shutdown文件。 您不能使用参数调用目标。 您只能服务。
但是我使用target来具有工作灵活性和有保证的动作顺序。
但是,最有趣的是后来。 机器必须关闭/重新启动。 共有2个选项:
- 用您自己的脚本替换reboot,shutdown和其他命令(在systemctl上它们仍然是符号链接),在脚本内,转到my_shutdown.target。 然后目标内的脚本将直接调用systemctl,例如systemctl reboot
- 比较简单,但我不喜欢该选项。 在所有接口中,请勿调用shutdown / reboot / others,而应直接调用目标系统。ctl孤立my_shutdown.target
我选择了第一个选项。 在systemd中,重新引导(如关闭电源)是systemd上的符号链接。
ls -l /sbin/poweroff lrwxrwxrwx 1 root root 14 30 18:23 /sbin/poweroff -> /bin/systemctl
因此,可以将它们替换为您自己的脚本:
重新启动