Linux开机启动配置文件SYSTEMD UNIT文件

开机启动的配置方式有多种,这里只介绍下通过systemctl方式启动,大部分都是翻译自Redhat官方文档。其他方式的启动自行查阅,现在我的强迫症越来越严重了,不舒服的东西要统统排斥~~!
systemd-681x220.jpeg

References:

其实之前也是查阅过各种各样的文章,但一直没有一个清晰的概念。这次看了官方文档之后,终于有些明白了,于是分享(估计也没人看,呜呜~~)一下。

systemd是一套Linux系统的基本构建块。它提供了一个系统和服务管理器,它以PID 1运行并启动系统的其余部分。它是一个系统守护进程(system daemon),在Unix/Linux下,它们是小写的,后缀为小写d。由于systemd管理系统(manages the system),因此称为systemd。就这么简单。

首先来说下使用systemd之后控制程序的方式:

$ sudo systemctl start foo.service 启动程序
$ sudo systemctl stop foo.service 停止程序
$ sudo systemctl enable foo.service 设置程序开机启动
$ sudo systemctl disable foo.service 禁止程序开机自启
$ sudo systemctl restart foo.service 重启程序
$ sudo systemctl status foo.service 查看程序运行状态
$ sudo systemctl is-enabled foo.service; echo $? 查看程序是否设置为开机自启,0-enabled 1-disabled

命令最后的.service可以省略不写。下面说明怎么设置开机启动:

  1. 创建一个service

    创建一个如下的.service文件,比如foo.service

    [Unit]
    Description=My service
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/python3 -u main.py
    WorkingDirectory=/home/pi/myscript
    StandardOutput=inherit
    StandardError=inherit
    Restart=always
    User=pi
    
    [Install]
    WantedBy=multi-user.target

    在这个例子中,service将会在工作目录/home/pi/myscript运行python3,目录中应该包含文件main.py。但是不仅限于python程序,只要将ExecStart后改成任何你想运行的程序或脚本都可以。配置文件具体内容在下面会介绍。

  2. 移动文件
    将这个.service文件以root身份移动到/etc/systemd/system,例如

    $ sudo cp foo.service /etc/systemd/system/foo.service
  3. 使用service
    移动之后就可以通过上文的控制命令启动或者停止service了。

配置文件的详细比较复杂,如果需要很细节的配置还是要查阅官方文档,没什么比官方文档更完整的了。下文摘取一些个人人文比较常用或者重要的说明一下:

文件结构:

nameDescription
[Unit]包含不依赖于Unit类型的通用选项。这些选项提供Unit描述,指定Unit的行为,并设置与其他Unit的依赖关系。
[unit type]如果Unit具有特定类型的指令,则这些指令将按照以单元类型命名的部分进行分组。例如,service unit文件包含[Service]部分。
[Install]包含Unit使用systemctl enable和disable命令安装的信息。
  • [Unit] 部分选项
OptionDescription
Description一个有意义的描述,这段文本会显示在systemctl status命令后的输出中。
Documentation提供unit引用文档的URI列表。
After定义unit的启动顺序,只有在指定的unit启动之后,此unit才会启动。与Requires不同,After不会明确激活制定的unit(博主注:即在指定的unit启动后,不会主动触发此unit,等待系统在某个合适的时间自动触发)。Before选项和After相反。
Requires配置对其他的unit的依赖,列出的unit将会随着此unit一起被激活。有任何依赖的unit启动失败,此unit都不会被激活。
Wants配置比Requires弱的依赖。列出的unit即使未启动成功,也不会影响此unit的激活。这是建立自定义unit依赖的推荐方式。
Conflicts配置冲突,和Requires相反。
  • [Service] 部分选项
OptionDescription
Type配置unit进程的启动类型,类型将影响ExecStart的功能和相关选项。
类型应是如下之一:

simple – 默认值,启动ExecStart的进程就是service的主进程。systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket 激活型。

forking – 启动ExecStart的进程会生成一个子进程,子进程会成为service的主进程。启动完成后,父进程退出。使用此启动类型应同时指定PIDFile=,以便systemd能够跟踪服务的主进程。(博主注:Debian中通过apt安装的nginx启动配置就是fork方式)

oneshot – 此类型和simple类似,但是会在启动后续unit之前退出。这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置RemainAfterExit=yes 使得systemd在服务进程退出之后仍然认为服务处于激活状态。

dbus – 此类型和simple类似,但后续unit仅在主进程获得D-Bus名称后启动。即当指定的BusName出现在DBus系统总线上时,systemd认为服务就绪。

notify – 此类型和simple类似,但是后续unit仅在sd_notify()函数发送通知消息后启动。即约定服务会在就绪后向systemd发送一个信号。

idle – 类似于simple,service二进制文件的实际执行被延后,直到所有的任务都处理完。这避免了状态输出和service的shell输出混合。
ExecStart指定 unit start 时需要执行的命令或脚本。ExecStartPre和ExecStartPost指定在ExecStart执行之前和之后需要执行的命令或脚本。Type=oneshot允许指定多条自定义命令,然后顺序执行。
ExecStop指定 unit stop 时需要执行的命令或脚本
ExecReload指定当 unit reload 时需要执行的命令或脚本。
Restart启用此选项后,service将在进程退出后重新启动,但通过systemctl命令停止的除外。
RemainAfterExit如果设置为true,即使退出所有进程,该service也会被视为激活状态。默认值为false,当设置Type=oneshot时,此选项特别有用。
  • [Install] 部分选项
OptionDescription
Alias为unit提供以空格分隔的别名列表。大部分的systemctl命令,除了systemctl enable,可以使用别名而不是实际的unit名字。
RequiredBy依赖于此unit的列表。当此unit设置为开机启动时,RequiredBy列表中的unit会增加一个对此unit的Require依赖。
WantedBy弱依赖于此unit的列表。当此unit设置为开机启动时,WantedBy列表中的unit会增加一个对此unit的Want依赖。
Also指定要与此unit一起安装或卸载的unit。
DefaultInstance仅限已实例化的unit,此选项指定开机启动unit的默认实例。详见:“Working with Instantiated Units”

手动翻译还是有点累,和文档比起来很少,但是总的来说常用的都包含了,这里感谢Arch Linux,文档写的太全了,基本只要看文档就能解决问题,而且汉化很不错,看起来轻松加愉快。
因为实际使用基本不会全部选项都用到,下面给出一个我自己用的模板供参考:

[Unit]
Description=My service                    # 描述
After=network.target                      # 在网络模块启动之后,启动此service,关于target参考Linux的运行级别

[Service]
Type=idle                                 # 启动类型,在系统启动工作完成后启动
ExecStart=/usr/bin/python3 -u main.py     # 执行程序
WorkingDirectory=/home/pi/myscript        # 工作目录 程序将会在此目录下执行
StandardOutput=inherit                    # 标准输出 继承自系统
StandardError=inherit                     # 标准错误输出 继承自系统
Restart=always                            # 自动重启
RestartSec=60                             # 自动重启前等待时间

[Install]
WantedBy=multi-user.target                # 该服务所在的target

标签: none

添加新评论

ali-01.gifali-58.gifali-09.gifali-23.gifali-04.gifali-46.gifali-57.gifali-22.gifali-38.gifali-13.gifali-10.gifali-34.gifali-06.gifali-37.gifali-42.gifali-35.gifali-12.gifali-30.gifali-16.gifali-54.gifali-55.gifali-59.gif

加载中……