• 17.3 systemctl 针对 service 类型的配置文件
    • 17.3.1 systemctl 配置文件相关目录简介
    • 17.3.2 systemctl 配置文件的设置项目简介
    • 17.3.3 两个 vsftpd 运行的实例
    • 17.3.4 多重的重复设置方式:以 getty 为例
    • 17.3.5 自己的服务自己作

    17.3 systemctl 针对 service 类型的配置文件

    以前,我们如果想要创建系统服务,就得要到 /etc/init.d/ 下面去创建相对应的 bash shell script 来处理。那么现在 systemd 的环境下面, 如果我们想要设置相关的服务启动环境,那应该如何处理呢?这就是本小节的任务啰!

    17.3.1 systemctl 配置文件相关目录简介

    现在我们知道服务的管理是通过 systemd,而 systemd 的配置文件大部分放置于 /usr/lib/systemd/system/ 目录内。但是 Red Hat 官方文件指出, 该目录的文件主要是原本软件所提供的设置,建议不要修改!而要修改的位置应该放置于 /etc/systemd/system/ 目录内。举例来说,如果你想要额外修改 vsftpd.service 的话, 他们建议要放置到哪些地方呢?

    • /usr/lib/systemd/system/vsftpd.service:官方释出的默认配置文件;
    • /etc/systemd/system/vsftpd.service.d/custom.conf:在 /etc/systemd/system 下面创建与配置文件相同文件名的目录,但是要加上 .d 的扩展名。然后在该目录下创建配置文件即可。另外,配置文件最好附文件名取名为 .conf 较佳! 在这个目录下的文件会“累加其他设置”进入 /usr/lib/systemd/system/vsftpd.service 内喔!
    • /etc/systemd/system/vsftpd.service.wants/*:此目录内的文件为链接文件,设置相依服务的链接。意思是启动了 vsftpd.service 之后,最好再加上这目录下面建议的服务。
    • /etc/systemd/system/vsftpd.service.requires/*:此目录内的文件为链接文件,设置相依服务的链接。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。
      基本上,在配置文件里面你都可以自由设置相依服务的检查,并且设置加入到哪些 target 里头去。但是如果是已经存在的配置文件,或者是官方提供的配置文件, Red Hat 是建议你不要修改原设置,而是到上面提到的几个目录去进行额外的客制化设置比较好!当然,这见仁见智~如果你硬要修改原始的 /usr/lib/systemd/system 下面的配置文件,那也是 OK 没问题的!并且也能够减少许多配置文件的增加~鸟哥自己认为,这样也不错!反正,就完全是个人喜好啰~

    17.3.2 systemctl 配置文件的设置项目简介

    了解了配置文件的相关目录与文件之后,再来,当然得要了解一下配置文件本身的内容了!让我们先来瞧一瞧 sshd.service 的内容好了! 原本想拿 vsftpd.service 来讲解,不过该文件的内容比较阳春,还是看一下设置项目多一些的 sshd.service 好了!

    1. [root@study ~]# cat /usr/lib/systemd/system/sshd.service
    2. [Unit] # 这个项目与此 unit 的解释、执行服务相依性有关
    3. Description=OpenSSH server daemon
    4. After=network.target sshd-keygen.service
    5. Wants=sshd-keygen.service
    6. [Service] # 这个项目与实际执行的指令参数有关
    7. EnvironmentFile=/etc/sysconfig/sshd
    8. ExecStart=/usr/sbin/sshd -D $OPTIONS
    9. ExecReload=/bin/kill -HUP $MAINPID
    10. KillMode=process
    11. Restart=on-failure
    12. RestartSec=42s
    13. [Install] # 这个项目说明此 unit 要挂载哪个 target 下面
    14. WantedBy=multi-user.target

    分析上面的配置文件,我们大概能够将整个设置分为三个部份,就是:

    • [Unit]: unit 本身的说明,以及与其他相依 daemon 的设置,包括在什么服务之后才启动此 unit 之类的设置值;
    • [Service], [Socket], [Timer], [Mount], [Path]..:不同的 unit type 就得要使用相对应的设置项目。我们拿的是 sshd.service 来当范本,所以这边就使用 [Service] 来设置。 这个项目内主要在规范服务启动的脚本、环境配置文件文件名、重新启动的方式等等。
    • [Install]:这个项目就是将此 unit 安装到哪个 target 里面去的意思!
      至于配置文件内有些设置规则还是得要说明一下:

    • 设置项目通常是可以重复的,例如我可以重复设置两个 After 在配置文件中,不过,后面的设置会取代前面的喔!因此,如果你想要将设置值归零, 可以使用类似“ After= ”的设置,亦即该项目的等号后面什么都没有,就将该设置归零了 (reset)。

    • 如果设置参数需要有“是/否”的项目 (布林值, boolean),你可以使用 1, yes, true, on 代表启动,用 0, no, false, off 代表关闭!随你喜好选择啰!
    • 空白行、开头为 # 或 ; 的那一行,都代表注解!
      每个部份里面还有很多的设置细项,我们使用一个简单的表格来说明每个项目好了!
    [Unit] 部份
    设置参数 参数意义说明
    Description 就是当我们使用 systemctl list-units 时,会输出给管理员看的简易说明!当然,使用 systemctl status 输出的此服务的说明,也是这个项目!
    Documentation 这个项目在提供管理员能够进行进一步的文件查询的功能!提供的文件可以是如下的数据:Documentation=http://www…. Documentation=man:sshd(8) Documentation=file:/etc/ssh/sshd_config
    After 说明此 unit 是在哪个 daemon 启动之后才启动的意思!基本上仅是说明服务启动的顺序而已,并没有强制要求里头的服务一定要启动后此 unit 才能启动。 以 sshd.service 的内容为例,该文件提到 After 后面有 network.target 以及 sshd-keygen.service,但是若这两个 unit 没有启动而强制启动 sshd.service 的话, 那么 sshd.service 应该还是能够启动的!这与 Requires 的设置是有差异的喔!
    Before 与 After 的意义相反,是在什么服务启动前最好启动这个服务的意思。不过这仅是规范服务启动的顺序,并非强制要求的意思。
    Requires 明确的定义此 unit 需要在哪个 daemon 启动后才能够启动!就是设置相依服务啦!如果在此项设置的前导服务没有启动,那么此 unit 就不会被启动!
    Wants 与 Requires 刚好相反,规范的是这个 unit 之后最好还要启动什么服务比较好的意思!不过,并没有明确的规范就是了!主要的目的是希望创建让使用者比较好操作的环境。 因此,这个 Wants 后面接的服务如果没有启动,其实不会影响到这个 unit 本身!
    Conflicts 代表冲突的服务!亦即这个项目后面接的服务如果有启动,那么我们这个 unit 本身就不能启动!我们 unit 有启动,则此项目后的服务就不能启动! 反正就是冲突性的检查啦!

    接下来了解一下在 [Service] 当中有哪些项目可以使用!

    [Service] 部份
    设置参数 参数意义说明
    Type 说明这个 daemon 启动的方式,会影响到 ExecStart 喔!一般来说,有下面几种类型 simple:默认值,这个 daemon 主要由 ExecStart 接的指令串来启动,启动后常驻于内存中。forking:由 ExecStart 启动的程序通过 spawns 延伸出其他子程序来作为此 daemon 的主要服务。原生的父程序在启动结束后就会终止运行。 传统的 unit 服务大多属于这种项目,例如 httpd 这个 WWW 服务,当 httpd 的程序因为运行过久因此即将终结了,则 systemd 会再重新生出另一个子程序持续运行后, 再将父程序删除。据说这样的性能比较好!!oneshot:与 simple 类似,不过这个程序在工作完毕后就结束了,不会常驻在内存中。dbus:与 simple 类似,但这个 daemon 必须要在取得一个 D-Bus 的名称后,才会继续运行!因此设置这个项目时,通常也要设置 BusName= 才行!idle:与 simple 类似,意思是,要执行这个 daemon 必须要所有的工作都顺利执行完毕后才会执行。这类的 daemon 通常是开机到最后才执行即可的服务!比较重要的项目大概是 simple, forking 与 oneshot 了!毕竟很多服务需要子程序 (forking),而有更多的动作只需要在开机的时候执行一次(oneshot),例如文件系统的检查与挂载啊等等的。
    EnvironmentFile 可以指定启动脚本的环境配置文件!例如 sshd.service 的配置文件写入到 /etc/sysconfig/sshd 当中!你也可以使用 Environment= 后面接多个不同的 Shell 变量来给予设置!
    ExecStart 就是实际执行此 daemon 的指令或脚本程序。你也可以使用 ExecStartPre (之前) 以及 ExecStartPost (之后) 两个设置项目来在实际启动服务前,进行额外的指令行为。 但是你得要特别注意的是,指令串仅接受“指令 参数 参数…”的格式,不能接受 <, >, >>, , & 等特殊字符,很多的 bash 语法也不支持喔! 所以,要使用这些特殊的字符时,最好直接写入到指令脚本里面去!不过,上述的语法也不是完全不能用,亦即,若要支持比较完整的 bash 语法,那你得要使用 Type=oneshot 才行喔! 其他的 Type 才不能支持这些字符。
    ExecStop 与 systemctl stop 的执行有关,关闭此服务时所进行的指令。
    ExecReload 与 systemctl reload 有关的指令行为
    Restart 当设置 Restart=1 时,则当此 daemon 服务终止后,会再次的启动此服务。举例来说,如果你在 tty2 使用文字界面登陆,操作完毕后登出,基本上,这个时候 tty2 就已经结束服务了。 但是你会看到屏幕又立刻产生一个新的 tty2 的登陆画面等待你的登陆!那就是 Restart 的功能!除非使用 systemctl 强制将此服务关闭,否则这个服务会源源不绝的一直重复产生!
    RemainAfterExit 当设置为 RemainAfterExit=1 时,则当这个 daemon 所属的所有程序都终止之后,此服务会再尝试启动。这对于 Type=oneshot 的服务很有帮助!
    TimeoutSec 若这个服务在启动或者是关闭时,因为某些缘故导致无法顺利“正常启动或正常结束”的情况下,则我们要等多久才进入“强制结束”的状态!
    KillMode 可以是 process, control-group, none 的其中一种,如果是 process 则 daemon 终止时,只会终止主要的程序 (ExecStart 接的后面那串指令),如果是 control-group 时, 则由此 daemon 所产生的其他 control-group 的程序,也都会被关闭。如果是 none 的话,则没有程序会被关闭喔!
    RestartSec 与 Restart 有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要 sleep 多少时间再重新启动的意思。默认是 100ms (毫秒)。

    最后,再来看看那么 Install 内还有哪些项目可用?

    [Install] 部份
    设置参数 参数意义说明
    WantedBy 这个设置后面接的大部分是 *.target unit !意思是,这个 unit 本身是附挂在哪一个 target unit 下面的!一般来说,大多的服务性质的 unit 都是附挂在 multi-user.target 下面!
    Also 当目前这个 unit 本身被 enable 时,Also 后面接的 unit 也请 enable 的意思!也就是具有相依性的服务可以写在这里呢!
    Alias 进行一个链接的别名的意思!当 systemctl enable 相关的服务时,则此服务会进行链接文件的创建!以 multi-user.target 为例,这个家伙是用来作为默认操作环境 default.target 的规划, 因此当你设置用成 default.target 时,这个 /etc/systemd/system/default.target 就会链接到 /usr/lib/systemd/system/multi-user.target 啰!

    大致的项目就有这些,接下来让我们根据上面这些数据来进行一些简易的操作吧!

    17.3.3 两个 vsftpd 运行的实例

    我们在上一章将 vsftpd 的 port 改成 555 号了。不过,因为某些原因,所以你可能需要使用到两个端口,分别是正常的 21 以及特殊的 555 ! 这两个 port 都启用的情况下,你可能就得要使用到两个配置文件以及两个启动脚本设置了!现在假设是这样:

    • 默认的 port 21:使用 /etc/vsftpd/vsftpd.conf 配置文件,以及 /usr/lib/systemd/system/vsftpd.service 设置脚本;
    • 特殊的 port 555:使用 /etc/vsftpd/vsftpd2.conf 配置文件,以及 /etc/systemd/system/vsftpd2.service 设置脚本。
      我们可以这样作:
    1. # 1\. 先创建好所需要的配置文件
    2. [root@study ~]# cd /etc/vsftpd
    3. [root@study vsftpd]# cp vsftpd.conf vsftpd2.conf
    4. [root@study vsftpd]# vim vsftpd.conf
    5. #listen_port=555
    6. [root@study vsftpd]# diff vsftpd.conf vsftpd2.conf
    7. 128c128
    8. &lt; #listen_port=555
    9. ---
    10. &gt; listen_port=555
    11. # 注意这两个配置文件的差别喔!只有这一行不同而已!
    12. # 2\. 开始处理启动脚本设置
    13. [root@study vsftpd]# cd /etc/systemd/system
    14. [root@study system]# cp /usr/lib/systemd/system/vsftpd.service vsftpd2.service
    15. [root@study system]# vim vsftpd2.service
    16. [Unit]
    17. Description=Vsftpd second ftp daemon
    18. After=network.target
    19. [Service]
    20. Type=forking
    21. ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf
    22. [Install]
    23. WantedBy=multi-user.target
    24. # 重点在改了 vsftpd2.conf 这个配置文件喔!
    25. # 3\. 重新载入 systemd 的脚本配置文件内容
    26. [root@study system]# systemctl daemon-reload
    27. [root@study system]# systemctl list-unit-files --all &#124; grep vsftpd
    28. vsftpd.service enabled
    29. vsftpd2.service disabled
    30. vsftpd@.service disabled
    31. vsftpd.target disabled
    32. [root@study system]# systemctl status vsftpd2.service
    33. vsftpd2.service - Vsftpd second ftp daemon
    34. Loaded: loaded (/etc/systemd/system/vsftpd2.service; disabled
    35. Active: inactive dead
    36. [root@study system]# systemctl restart vsftpd.service vsftpd2.service
    37. [root@study system]# systemctl enable vsftpd.service vsftpd2.service
    38. [root@study system]# systemctl status vsftpd.service vsftpd2.service
    39. vsftpd.service - Vsftpd ftp daemon
    40. Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; enabled
    41. Active: active running since Wed 2015-08-12 22:00:17 CST; 35s ago
    42. Main PID: 12670 vsftpd
    43. CGroup: /system.slice/vsftpd.service
    44. └─12670 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
    45. Aug 12 22:00:17 study.centos.vbird systemd[1]: Started Vsftpd ftp daemon.
    46. vsftpd2.service - Vsftpd second ftp daemon
    47. Loaded: loaded (/etc/systemd/system/vsftpd2.service; enabled
    48. Active: active running since Wed 2015-08-12 22:00:17 CST; 35s ago
    49. Main PID: 12672 vsftpd
    50. CGroup: /system.slice/vsftpd2.service
    51. └─12672 /usr/sbin/vsftpd /etc/vsftpd/vsftpd2.conf
    52. [root@study system]# netstat -tlnp
    53. Active Internet connections only servers
    54. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    55. tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1340/sshd
    56. tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2387/master
    57. tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd
    58. tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd
    59. tcp6 0 0 :::22 :::* LISTEN 1340/sshd
    60. tcp6 0 0 ::1:25 :::* LISTEN 2387/master

    很简单的将你的 systemd 所管理的 vsftpd 做了另一个服务!未来如果有相同的需求,同样的方法作一遍即可!

    17.3.4 多重的重复设置方式:以 getty 为例

    我们的 CentOS 7 开机完成后,不是说有 6 个终端机可以使用吗?就是那个 tty1~tty6 的啊!那个东西是由 agetty 这个指令达成的。 OK!那么这个终端机的功能又是从哪个项目所提供的呢?其实,那个东东涉及很多层面,主要管理的是 getty.target 这个 target unit , 不过,实际产生 tty1~tty6 的则是由 getty@.service 所提供的!咦!那个 @ 是啥东西?

    先来查阅一下 /usr/lib/systemd/system/getty@.service 的内容好了:

    1. [root@study ~]# cat //usr/lib/systemd/system/getty@.service
    2. [Unit]
    3. Description=Getty on %I
    4. Documentation=man:agetty8 man:systemd-getty-generator8
    5. Documentation=http://0pointer.de/blog/projects/serial-console.html
    6. After=systemd-user-sessions.service plymouth-quit-wait.service
    7. After=rc-local.service
    8. Before=getty.target
    9. ConditionPathExists=/dev/tty0
    10. [Service]
    11. ExecStart=-/sbin/agetty --noclear %I $TERM
    12. Type=idle
    13. Restart=always
    14. RestartSec=0
    15. UtmpIdentifier=%I
    16. TTYPath=/dev/%I
    17. TTYReset=yes
    18. TTYVHangup=yes
    19. TTYVTDisallocate=yes
    20. KillMode=process
    21. IgnoreSIGPIPE=no
    22. SendSIGHUP=yes
    23. [Install]
    24. WantedBy=getty.target

    比较重要的当然就是 ExecStart 项目啰!那么我们去 man agetty 时,发现到它的语法应该是“ agetty —noclear tty1 ”之类的字样, 因此,我们如果要启动六个 tty 的时候,基本上应该要有六个启动配置文件。亦即是可能会用到 getty1.service, getty2.service…getty6.service 才对! 哇!这样控管很麻烦啊~所以,才会出现这个 @ 的项目啦!咦!这个 @ 到底怎么回事呢?我们先来看看 getty@.service 的上游,亦即是 getty.target 这个东西的内容好了!

    1. [root@study ~]# systemctl show getty.target
    2. # 那个 show 的指令可以将 getty.target 的默认设置值也取出来显示!
    3. Names=getty.target
    4. Wants=getty@tty1.service
    5. WantedBy=multi-user.target
    6. Conflicts=shutdown.target
    7. Before=multi-user.target
    8. After=getty@tty1.service getty@tty2.service getty@tty3.service getty@tty4.service
    9. getty@tty6.service getty@tty5.service
    10. .....(后面省略).....

    你会发现,咦!怎么会多出六个怪异的 service 呢?我们拿 getty@tty1.service 来说明一下好了!当我们执行完 getty.target 之后, 他会持续要求 getty@tty1.service 等六个服务继续启动。那我们的 systemd 就会这么作:

    • 先看 /usr/lib/systemd/system/, /etc/systemd/system/ 有没有 getty@tty1.service 的设置,若有就执行,若没有则执行下一步;
    • 找 getty@.service 的设置,若有则将 @ 后面的数据带入成 %I 的变量,进入 getty@.service 执行!
      这也就是说,其实 getty@tty1.service 实际上是不存在的!他主要是通过 getty@.service 来执行~也就是说, getty@.service 的目的是为了要简化多个执行的启动设置, 他的命名方式是这样的:
    1. 原始文件:执行服务名称@.service
    2. 可执行文件案:执行服务名称@范例名称.service

    因此当有范例名称带入时,则会有一个新的服务名称产生出来!你再回头看看 getty@.service 的启动脚本:

    1. ExecStart=-/sbin/agetty --noclear %I $TERM

    上表中那个 %I 指的就是“范例名称”!根据 getty.target 的信息输出来看,getty@tty1.service 的 %I 就是 tty1 啰!因此执行脚本就会变成“ /sbin/agetty —noclear tty1 ”! 所以我们才有办法以一个配置文件来启动多个 tty1 给用户登陆啰!

    • 将 tty 的数量由 6 个降低到 4 个
      现在你应该要感到困扰的是,那么“ 6 个 tty 是谁规定的”为什么不是 5 个还是 7 个?这是因为 systemd 的登陆配置文件 /etc/systemd/logind.conf 里面规范的啦! 假如你想要让 tty 数量降低到剩下 4 个的话,那么可以这样实验看看:
    1. # 1\. 修改默认的 logind.conf 内容,将原本 6 个虚拟终端机改成 4 个
    2. [root@study ~]# vim /etc/systemd/logind.conf
    3. [Login]
    4. NAutoVTs=4
    5. ReserveVT=0
    6. # 原本是 6 个而且还注解,请取消注解,然后改成 4 吧!
    7. # 2\. 关闭不小心启动的 tty5, tty6 并重新启动 getty.target 啰!
    8. [root@study ~]# systemctl stop getty@tty5.service
    9. [root@study ~]# systemctl stop getty@tty6.service
    10. [root@study ~]# systemctl restart systemd-logind.service

    现在你再到桌面环境下,按下 [ctrl]+[alt]+[F1]~[F6] 就会发现,只剩下四个可用的 tty 啰!后面的 tty5, tty6 已经被放弃了!不再被启动喔! 好!那么我暂时需要启动 tty8 时,又该如何处理呢?需要重新创建一个脚本吗?不需要啦!可以这样作!

    1. [root@study ~]# systemctl start getty@tty8.service

    无须额外创建其他的启动服务配置文件喔!

    • 暂时新增 vsftpd 到 2121 端口
      不知道你有没有发现,其实在 /usr/lib/systemd/system 下面还有个特别的 vsftpd@.service 喔!来看看他的内容:
    1. [root@study ~]# cat /usr/lib/systemd/system/vsftpd@.service
    2. [Unit]
    3. Description=Vsftpd ftp daemon
    4. After=network.target
    5. PartOf=vsftpd.target
    6. [Service]
    7. Type=forking
    8. ExecStart=/usr/sbin/vsftpd /etc/vsftpd/%i.conf
    9. [Install]
    10. WantedBy=vsftpd.target

    根据前面 getty@.service 的说明,我们知道在启动的脚本设置当中, %i 或 %I 就是代表 @ 后面接的范例文件名的意思! 那我能不能创建 vsftpd3.conf 文件,然后通过该文件来启动新的服务呢?就来玩玩看!

    1. # 1\. 根据 vsftpd@.service 的建议,于 /etc/vsftpd/ 下面先创建新的配置文件
    2. [root@study ~]# cd /etc/vsftpd
    3. [root@study vsftpd]# cp vsftpd.conf vsftpd3.conf
    4. [root@study vsftpd]# vim vsftpd3.conf
    5. listen_port=2121
    6. # 2\. 暂时启动这个服务,不要永久启动他!
    7. [root@study vsftpd]# systemctl start vsftpd@vsftpd3.service
    8. [root@study vsftpd]# systemctl status vsftpd@vsftpd3.service
    9. vsftpd@vsftpd3.service - Vsftpd ftp daemon
    10. Loaded: loaded (/usr/lib/systemd/system/vsftpd@.service; disabled
    11. Active: active running since Thu 2015-08-13 01:34:05 CST; 5s ago
    12. [root@study vsftpd]# netstat -tlnp
    13. Active Internet connections only servers
    14. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    15. tcp6 0 0 :::2121 :::* LISTEN 16404/vsftpd
    16. tcp6 0 0 :::555 :::* LISTEN 12672/vsftpd
    17. tcp6 0 0 :::21 :::* LISTEN 12670/vsftpd

    因为我们启用了 vsftpd@vsftpd3.service ,代表要使用的配置文件在 /etc/vsftpd/vsftpd3.conf 的意思!所以可以直接通过 vsftpd@.service 而无须重新设置启动脚本! 这样是否比前几个小节的方法还要简便呢? ^^。通过这个方式,你就可以使用到新的配置文件啰!只是你得要注意到 @ 这个东西就是了! ^^

    鸟哥的图示

    Tips 聪明的读者可能立刻发现一件事,为啥这次 FTP 增加了 2121 端口却不用修改 SELinux 呢?这是因为默认启动小于 1024 号码以下的端口时, 需要使用到 root 的权限,因此小于 1024 以下端口的启动较可怕。而这次范例中,我们使用 2121 端口,他对于系统的影响可能小一些 (其实一样可怕!), 所以就忽略了 SELinux 的限制了!

    17.3.5 自己的服务自己作

    我们来仿真自己作一个服务吧!假设我要作一只可以备份自己系统的服务,这只脚本我放在 /backups 下面,内容有点像这样:

    1. [root@study ~]# vim /backups/backup.sh
    2. #!/bin/bash
    3. source="/etc /home /root /var/lib /var/spool/{cron,at,mail}"
    4. target="/backups/backup-system-$(date +%Y-%m-%d).tar.gz"
    5. [ ! -d /backups ] && mkdir /backups
    6. tar -zcvf ${target} ${source} &&gt; /backups/backup.log
    7. [root@study ~]# chmod a+x /backups/backup.sh
    8. [root@study ~]# ll /backups/backup.sh
    9. -rwxr-xr-x. 1 root root 220 Aug 13 01:57 /backups/backup.sh
    10. # 记得要有可执行的权限才可以喔!

    接下来,我们要如何设计一只名为 backup.service 的启动脚本设置呢?可以这样做喔!

    1. [root@study ~]# vim /etc/systemd/system/backup.service
    2. [Unit]
    3. Description=backup my server
    4. Requires=atd.service
    5. [Service]
    6. Type=simple
    7. ExecStart=/bin/bash -c " echo /backups/backup.sh &#124; at now"
    8. [Install]
    9. WantedBy=multi-user.target
    10. # 因为 ExecStart 里面有用到 at 这个指令,因此, atd.service 就是一定要的服务!
    11. [root@study ~]# systemctl daemon-reload
    12. [root@study ~]# systemctl start backup.service
    13. [root@study ~]# systemctl status backup.service
    14. backup.service - backup my server
    15. Loaded: loaded (/etc/systemd/system/backup.service; disabled
    16. Active: inactive dead
    17. Aug 13 07:50:31 study.centos.vbird systemd[1]: Starting backup my server...
    18. Aug 13 07:50:31 study.centos.vbird bash[20490]: job 8 at Thu Aug 13 07:50:00 2015
    19. Aug 13 07:50:31 study.centos.vbird systemd[1]: Started backup my server.
    20. # 为什么 Active 是 inactive 呢?这是因为我们的服务仅是一个简单的 script 啊!
    21. # 因此执行完毕就完毕了,不会继续存在内存中喔!

    完成上述的动作之后,以后你都可以直接使用 systemctl start backup.service 进行系统的备份了!而且会直接丢进 atd 的管理中, 你就无须自己手动用 at 去处理这项任务了~好像还不赖喔! ^_^

    这样自己做一个服务好像也不难啊! ^_^!自己动手玩玩看吧!

    原文: https://wizardforcel.gitbooks.io/vbird-linux-basic-4e/content/150.html