systemd&&定时任务

2114 字
11 分钟
systemd&&定时任务

systemd&&定时任务#

[TOC]


systemctl#

在Linux系统(特别是Centos7)中对服务进行启动、关闭、重启的操作使用sytemctl

  • systemctl start xx

  • systemctl stop xx

  • systemctl restart xx

  • systemctl status xx

  • systemctl reload xx

Terminal window
状态查询命令:
[root@Rocky10 ~]# systemctl status sshd
sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; preset: enabled)
Active: active (running) since Fri 2026-03-06 09:12:51 CST; 7h ago
Invocation: 982b5a7bcc964c5f99bc720ec3a786d4
Docs: man:sshd(8)
man:sshd_config(5)
=======================================
'更方便的判断!'
root@rocky10:~# systemctl is-(tab补齐)
is-active is-enabled....
(1)验证服务是否处于活动状态
[root@Rocky10 ~]# systemctl is-active sshd
active
(2)验证单元是否处于开机自启状态!
[root@Rocky10 ~]# systemctl is-enabled sshd
enabled
=======================================
'列出当前系统所有正在活跃的服务'
[root@Rocky10 ~]# systemctl list-units --type=service --state=active
UNIT LOAD ACTIVE SUB DESCRIPTION
accounts-daemon.service loaded active running Accounts Service
alsa-state.service loaded active running Manage
atd.service loaded active running Deferred
auditd.service loaded active running Security
..............
=======================================
'列出当前系统所有设置为开机自启的服务'
[root@Rocky10 ~]# systemctl list-unit-files --type=service --state=enabled
UNIT FILE STATE PRESET
accounts-daemon.service enabled enabled
atd.service enabled enabled
audit-rules.service enabled enabled
auditd.service enabled enabled
..............
=======================================
'屏蔽与取消屏蔽:'
systemctl mask name.service
# 屏蔽服务
(创建指向/dev/null的链接,阻止启动)
systemctl unmask name.service
# 取消屏蔽服务
⚠️注意:disable的服务可手动启动,mask的服务则完全无法启动
[root@Rocky10 ~]# ps -ef | grep crond
root 1417 1 0 09:12 ? 00:00:00 /usr/sbin/crond -n
# 定时任务服务!
[root@Rocky10 ~]# systemctl mask crond
Created symlink '/etc/systemd/system/crond.service' '/dev/null'.
# 定向到空!
[root@Rocky10 ~]# systemctl start crond
Failed to start crond.service: Unit crond.service is masked.
# 屏蔽后,无法手动启动!
[root@Rocky10 ~]# systemctl unmask crond
Removed '/etc/systemd/system/crond.service'.
[root@Rocky10 ~]# systemctl is-active crond
active

服务单元结构#

systemd 使用 unit 文件 来管理系统资源

常见的 unit 类型包括:

  • .service:定义一个服务(进程)
  • .timer:定义定时器(类似 cron,但更强大)
  • .socket:用于 socket 激活(按需启动服务)
  • .target:类似于运行级别(如 multi-user.target)

所有 unit 文件通常放在 以下目录(按优先级从高到低):

  1. /etc/systemd/system/ - 管理员自定义配置(最高优先级)
  2. /run/systemd/system/ - 运行时生成的配置
  3. /usr/lib/systemd/system/ - 系统默认配置
Terminal window
'如何启停服务'
假设你有一个名为 myapp.service 的服务:
systemctl restart myapp.service
....
# 参考上面的笔记!
⚠️注意:.service 后缀可省略
================================================
systemctl start myapp 等价于 start myapp.service
================================================
如果你是通过,编译安装Nginx,而且没有通过yum安装
那么你不能够通过systemctl进行管理,比如服务的启动,暂停...
必须手动书写服务的配置、格式如下!!!
Terminal window
'单元文件结构'
[Unit]
# 主要用于定义服务的依赖关系和描述信息!
Description=服务描述
After=network.target remote-fs.target
# 定义启动顺序(此服务在指定目标之后启动)
Before=xxx
# 在某个 unit 启动之前启动本unit
Requires=依赖服务.service
# 强依赖(依赖服务必须成功启动)
# 若依赖项失败,本 unit 也失败
Wants=依赖服务.service
# 弱依赖,即使依赖项失败,本 unit 仍尝试启动
[Service]
Type=forking|simple|oneshot|notify
# 服务类型
ExecStart=/usr/sbin/服务名
# 启动命令
ExecReload=/bin/kill -s HUP $MAINPID
# 重载配置命令
ExecStop=/bin/kill -SIGTERM $MAINPID
# $MAINPID 是一个 systemd 变量,它代表服务的主进程ID
# 这条命令的作用是向主进程发送一个标准的终止信号
# 这是停止服务的正确方式
PIDFile=/run/服务名.pid
# 可以用一个文件来记录服务的pid
Restart=always
# 什么时候重启?
always:任何退出都重启
# 除非手动 systemctl stop,它不会重启!
TimeoutStopSec=5
# 停止服务的超时时间
# 最多等待 5 秒,如果 5 秒后进程仍未退出,systemd 将强制杀死它
[Install]
WantedBy=multi-user.target
# 控制服务在什么系统运行级别(target)下自动启动
# 当系统进入这个运行级别时,会自动启动本服务
'大多数运行级别为3即可'

👑实验案例#

编写一个简单的 service 单元(执行脚本)

  • 场景:每天都输出 当前时间 到 /home/test.txt
Terminal window
步骤 1:创建脚本
/server/sh/log-time.sh
[root@R11 sh]# pwd
/server/sh
[root@R11 sh]# vim log-time.sh
#!/bin/bash
echo "$(date): Hello from systemd timer!" >> /home/test.txt
[root@R11 sh]# chmod +x log-time.sh
[root@R11 sh]# ll log-time.sh
-rwxr-xr-x 1 root root 72 Mar 14 16:28 log-time.sh
步骤 2:创建 service 文件
/etc/systemd/system/log-time.service
================
!注意是service并不是server
================
[root@R11 sh]# vim /etc/systemd/system/log-time.service
[Unit]
Description=time to /home/test.txt
After=network.target
# 在网络服务启动起来之后,启动
[Service]
Type=oneshot
# 表示执行完就退出,适合一次性任务
ExecStart=/server/sh/log-time.sh
# 启动命令
# User=www
# Group=www
# !前提是这个用户得有权限!
# 可选:指定运行用户(避免 root 写文件)
[Install]
WantedBy=multi-user.target
[root@R11 sh]# ll /etc/systemd/system/log-time.service
-rw-r--r-- 1 root root 178 Mar 14 16:34 /etc/systemd/system/log-time.service
步骤 3:创建对应的 timer 文件
/etc/systemd/system/log-time.timer
关键规则:.timer 文件名必须与 .service 文件名前缀一致
# (即 log-time.timer 对应 log-time.service)
[root@R11 sh]# vim /etc/systemd/system/log-time.timer
[Unit]
Description=Run log-time.service every day
Requires=log-time.service
# 强依赖于我们刚才写的service服务
[Timer]
OnCalendar=daily
# 每天运行一次(默认通常是午夜 00:00)
# 或更精确:OnCalendar=*-*-* 02:00:00
Persistent=true
# 即使系统在预定触发时间关机或休眠了,当系统再次启动后,如果错过了触发时间,也会立即补执行一次
[Install]
WantedBy=timers.target
步骤 4:启用并启动 timer
[root@R11 sh]# systemctl daemon-reload
# 重载 systemd 配置
[root@R11 sh]# systemctl enable --now log-time.timer
# 启用并启动 timer
⚠️ 不要手动 start log-time.service,它应由 timer 触发
# 这里启动的是.timer
[root@R11 sh]# systemctl status log-time.timer
log-time.timer - Run log-time.service every day
Loaded: loaded (/etc/systemd/system/log-time.timer; enabled; preset: disabled)
Active: active (waiting) since Sat 2026-03-14 16:58:43 CST; 15s ago
Invocation: 6f95ba8ec5044123abb448cdd024a5e3
Trigger: Sun 2026-03-15 00:00:00 CST; 7h left
Triggers: log-time.service
Mar 14 16:58:43 R11 systemd[1]: Started log-time.timer - Run log-time.service every day
[root@R11 sh]# ll /home/
total 0
[root@R11 sh]# systemctl restart log-time.timer
[root@R11 sh]# journalctl -u log-time.service | tail -3
# 查看指定服务的日志
Mar 14 18:03:47 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
# 启动服务..
Mar 14 18:03:47 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 14 18:03:47 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 成功写入!!
[root@R11 sh]# ll /home/
total 4
-rw-r--r-- 1 root root 177 Mar 14 18:03 test.txt
# 重启完服务就会手动执行一次定时任务
[root@R11 sh]# cat /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
OnCalendar=daily
# 每天运行一次(默认通常是午夜 00:00)

OnCalendar#

OnCalendar 支持类似 cron 的语法,但更灵活:

示例含义
daily每天 00:00
hourly每小时
*-*-* 14:30:00每天 14:30
Mon..Fri *-*-* 09:00:00工作日上午 9 点
*:0/5每 5 分钟
Terminal window
[root@R11 sh]# systemctl list-timers
# 查看所有的定时任务
NEXT LEFT LAST PASSED UNIT
.........
Sun..03-15 00:00 6h 2026-03-14.. - log-time.timer
列名(关键字)含义说明
NEXT下一次定时器将触发的时间
LEFT距离下一次触发还剩余的时间(例如 “6h” 表示还有 6 小时)
LAST上一次定时器实际触发的时间
PASSED自上一次触发以来已经过去的时间(例如 “2min ago”)、若尚未触发过,则显示 - 或留空
UNIT对应的定时器单元名称(以 .timer 结尾),它控制一个关联的 .service 单元
Terminal window
# 也可以通过修改时间进行触发!
# 下一次触发的时间在03-15 00:00:00
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
[root@R11 sh]# date
Sat Mar 14 06:10:50 PM CST 2026
# 现在的时间⌚️
[root@R11 sh]# date -s "2026-03-14 23:59:50"
Sat Mar 14 11:59:50 PM CST 2026
# 手动修改
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
[root@R11 sh]# tail -1 /home/test.txt
Sat Mar 14 06:03:47 PM CST 2026: Hello from systemd timer!
# 我又查了几次,还是没有写入、此时我有点怀疑我自己了已经!
[root@R11 sh]# date
Sun Mar 15 12:00:15 AM CST 2026
# 又看了眼时间!已经过00:00:00了呀!
[root@R11 sh]# journalctl -u log-time.service | tail -3
Mar 14 18:03:47 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
Mar 14 18:03:47 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 14 18:03:47 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 又看了眼日志,还是上次的日志呀!!
[root@R11 sh]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
....
Mon 2026-03-16 00:00:00 CST 23h Sun 2026-03-15 00:00:27 CST 17s ago log-time.timer log-time.service
# 但是你看下一次执行的时间已经变了!变成03-16了
# 下一次执行触发的时间要23个小时
# 上一次触发的时间为03-15 00:00:27
'说明它是执行过的呀!'
[root@R11 sh]# tail -1 /home/test.txt
Sun Mar 15 12:00:27 AM CST 2026: Hello from systemd timer!
# 又cat了一次终于出来了!
[root@R11 sh]# journalctl -u log-time.service | tail -3
Mar 15 00:00:27 R11 systemd[1]: Starting log-time.service - time to /home/test.txt...
Mar 15 00:00:27 R11 systemd[1]: log-time.service: Deactivated successfully.
Mar 15 00:00:27 R11 systemd[1]: Finished log-time.service - time to /home/test.txt.
# 又看了一眼日志,也是成功运行了起来!
'那么如何把时间改回✅️正确的呢?'
[root@R11 sh]# date
Sun Mar 15 12:09:07 AM CST 2026
[root@R11 sh]# systemctl restart chronyd
# 静静地等待一会ing
.........
[root@R11 sh]# date
Sun Mar 15 12:09:27 AM CST 2026
[root@R11 sh]# date
Sat Mar 14 06:21:06 PM CST 2026
# 变回来了,下午六点半

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

systemd&&定时任务
https://www.kpyun.fun/posts/basics/extension/extension07/
作者
久棹
发布于
2025-09-23
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
久棹
只要胆子大,天天寒暑假!
公告
欢迎来到久棹的技术小站!本站专注 Linux 运维学习笔记分享,如有问题欢迎交流探讨 🎉
分类
标签
站点统计
文章
98
分类
11
标签
203
总字数
244,453
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
Firefly v6.13.5
文章许可
CC BY-NC-SA 4.0

文章目录