13-Linux学习之旅之Linux系统启动过程+Systemd+计划任务
Linux学习之旅之Linux系统启动过程+Systemd+计划任务
一、Linux启动流程全景
1、启动链路
| 阶段 | 执行组件 | 核心作用 |
|---|---|---|
| 1 BLOS/UEFI 自检 | 主板 UEFI 固件 | 1. 并行检测 CPU、内存、硬盘、网卡等硬件 2. 读取启动项顺序,识别 GPT 磁盘、ESP 分区 3. 支持 Secure Boot 校验引导文件合法性 |
| 2 EFI 引导 | GRUB引导程序 | 1. 提供开机启动菜单,可选内核 / 救援模式 2. 加载内核 vmlinuz 与临时镜像 initramfs 3. 向内核传递 root 磁盘、selinux 等启动参数 |
| 3 内核初始化 | Linux 内核 + initramfs | 1. 解压内核,初始化内存、中断、总线设备 2. 通过 initramfs 加载 LVM/RAID/ 硬盘驱动 3. 识别真实根分区,执行 switch_root 切换磁盘根目录 |
| 4 启动一号进程 | systemd(PID=1) | 1. 挂载 /proc/sys 虚拟文件系统,加载 /etc/fstab 所有分区 2. udev 扫描硬件生成 /dev 设备文件 3. 按 target 并行启动日志、网络、ssh 等系统服务 |
| 5 登录交互 | getty/gdm 登录管理器 | 1. 到达 multi-user/graphical 目标 2. 开启字符终端或图形登录界面 3. 用户登录,加载 shell 环境,系统启动完成 |
2、启动流程关键文件
| 文件 / 目录 | Rocky 10(RHEL 系) | Ubuntu 26.04(Debian 系) |
|---|---|---|
| 内核文件 | /boot/vmlinuz-* |
/boot/vmlinuz-* |
| initramfs 临时镜像 | /boot/initramfs-*.img |
/boot/initrd.img-* |
| GRUB 开机菜单配置 | /boot/grub2/grub.cfg |
/boot/grub/grub.cfg |
| GRUB 全局默认参数 | /etc/default/grub |
/etc/default/grub |
| systemd 默认启动目标软链接 | /etc/systemd/system/default.target |
/etc/systemd/system/default.target |
二、GRUB2引导配置
1、什么是GRUB2
GRUB2是Linux系统最常用的引导加载程序(Boot Loader)。它的核心职责:
允许用户选择启动哪个操作系统或内核版本
向内核传递启动参数(如调整运行级别、启用调试模式)
提供救援模式入口
2、/etc/default/grub核心参数
[root@rockyser ~]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=2G-64G:256M,64G-:512M resume=UUID=d2b26166-805f-4682-88e2-69ebcfaf6c4d rd.lvm.lv=rl_bogon/root rd.lvm.lv=rl_bogon/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
------------------------------------------
#GRUB_TIMEOUT=5
开机 GRUB 菜单等待 5 秒,超时自动启动默认内核;设为 0 直接跳过菜单,-1无限等待。
#GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
自动获取系统发行名称(执行 sed 截取/etc/system-release,输出Rocky Linux),用于菜单标题展示。
#GRUB_DEFAULT=saved
记住上次启动的内核,下次开机默认选中上次使用条目;
可选值:数字0(第一条内核)、saved、内核完整名称。
#GRUB_DISABLE_SUBMENU=true
关闭内核子菜单,所有内核版本平铺展示,不会折叠旧内核。
#GRUB_TERMINAL_OUTPUT="console"
GRUB 菜单输出到物理控制台(服务器本地显示器),远程无图形菜单。
#GRUB_CMDLINE_LINUX="xxx"
最重要参数:内核启动命令行,内核启动时读取该串配置
3、常见内核启动参数
| 参数 | 作用 | 适用场景 |
|---|---|---|
rhgb |
Red Hat Graphical Boot,图形化启动,展示开机进度条 | RHEL/Rocky/CentOS 系列系统默认自带 |
quiet |
静默模式,屏蔽大量内核启动日志输出 | 生产服务器,减少启动刷屏日志干扰 |
single / 1 |
进入传统单用户模式 | 旧版系统重置 root 密码、简单系统修复 |
systemd.unit=rescue.target |
救援模式,根分区以只读方式挂载,基础服务启动 | 文件系统损坏、磁盘异常修复 |
systemd.unit=emergency.target |
紧急模式,不自动挂载任何磁盘,仅提供最小 shell | 根分区无法识别、fstab 错误无法开机 |
rd.break |
在 initramfs 临时文件系统阶段中断启动,进入内存 shell | RHEL 系无密码重置 root 密码、LVM 磁盘故障排查 |
4、修改GRUB配置(请做好快照)
跳过等待时间
[root@rockyser ~]# vim /etc/default/grub
[root@rockyser ~]# cat /etc/default/grub
GRUB_TIMEOUT=0 #改为0,源参数5
#重新生成GRUB配置文件 Ubuntu命令为:update-grub
[root@rockyser ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
done
#重启试试有没有跳过
[root@rockyser ~]# reboot
禁用图形化启动
[root@rockyzm ~]# vim /etc/default/grub
[root@rockyzm ~]# cat /etc/default/grub
GRUB_CMDLINE_LINUX=""
#重新生成GRUB配置文件 Ubuntu命令为:update-grub
[root@rockyzm ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for UEFI Firmware Settings ...
done
#重启试试
[root@rockyzm ~]# reboot
如果没有还是GUI启动可以试着按一下键盘Esc
5、修改GRUB配置流程
1 编辑/etc/default/grub
2 重新生成配置文件:rocky:grub2-mkconfig -o /boot/grub2/grub.cfg
ubuntu:update-grub
3 重启生效 reboot
4 验证
真正的配置文件存放位置rocky:/boot/grub2/grub.cfg
Ubuntu:/boot/grub/grub.cfg
三、运行级别与systemd target
1、运行级别
SysVinit是Linux早期使用的初始化系统,使用运行级别(Runlevel) 来控制系统状态
| 运行级别 | 编号 | 作用 |
|---|---|---|
| 关机 | 0 | 系统断电停机 |
| 单用户模式 | 1/S/single | 无网络、仅 root,修复系统 / 重置密码 |
| 多用户字符模式 | 2 | Debian/Ubuntu:带网络字符界面;RHEL 系未使用 |
| 完整多用户字符 | 3 | RHEL/Rocky 服务器默认,无图形桌面、支持网络 |
| 未使用 | 4 | 预留自定义级别,发行版默认空置 |
| 图形多用户 | 5 | 启动 X11 图形桌面(GNOME/KDE) |
| 重启 | 6 | 系统重启 |
systemd使用target替代了传统的运行级别
| 传统 sysvinit 运行级别 | systemd target | 官方说明 & 发行版差异 |
|---|---|---|
| 0 | poweroff.target |
关机,系统断电停机 |
| 1 | rescue.target |
单用户 / 救援模式,根分区只读挂载,基础修复环境 |
| 2 | multi-user.target |
Debian/Ubuntu:无网络多用户字符模式;RHEL 系无区分,同级别 3 |
| 3 | multi-user.target |
RHEL/Rocky 服务器默认:带完整网络的纯字符命令行 |
| 4 | multi-user.target |
系统预留自定义级别,所有发行版均未单独使用 |
| 5 | graphical.target |
图形桌面模式,加载 X11/GTK 图形界面、显示管理器 |
| 6 | reboot.target |
系统重启 |
2、查看和切换运行级别/target
查看当前target:
[root@rockyser ~]# systemctl get-default
multi-user.target
# 或查看链接
[root@rockyser ~]# ls -l /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 41 7月20日 14:03 /etc/systemd/system/default.target -> /usr/lib/systemd/system/multi-user.target
切换target(临时)
# 切换到救援模式
[root@rockyser ~]# systemctl rescue
# 切换到紧急模式
[root@rockyser ~]# systemctl emergency
# 重启系统
[root@rockyser ~]# systemctl reboot
# 关机
[root@rockyser ~]# systemctl poweroff
设置默认永久target
# 设置为命令行模式
[root@rockyser ~]# systemctl set-default multi-user.target
# 设置为图形界面模式(前提安装了GUI)
[root@rockyser ~]# systemctl set-default graphical.target
四、单用户模式与救援模式
1、什么是单用户模式
单用户模式是一种维护模式,用于:
重置root密码(忘记root密码时)
修复文件系统错误
排查启动故障
移除损坏的软件包
2、进入单用户模式与修改root密码(通过GRUB)
GRUB进入方式
# 1. 重启系统,在GRUB菜单按 e 键编辑启动项
# 2. 找到 linux 开头的行(内核启动参数行)
# 3. 在行末添加 rd.break(中断启动进入initramfs)
# 4. 按 Ctrl+x 启动
开启时在GRUB菜单将光标键盘↑↓移到,单击键盘e进入单用户模式

在linux开头行末尾加入rd.break(中断启动进入initramfs),按键盘Ctrl+x 启动
Ubuntu末尾加入single或1或systemd.unit=rescue.target

1、进入后按键盘Enter进入救援模式
2、进入后,根文件系统挂载在 /sysroot,需要重新挂载为读写mount -o remount,rw /sysroot
3、chroot /sysroot
4、passwd root
5、touch /.autorelabel # SELinux重新标记(Rocky需要)
注:ubuntu可以省略2、3、5

退出并重启

五、启动排障常用操作
查看启动日志
# 查看本次启动日志
[root@rockyser ~]# journalctl -b
# 查看上次启动的日志(排查重启原因)
[root@rockyser ~]# journalctl -b -1
# 查看启动过程中失败的服务
[root@rockyser ~]# systemctl --failed
# 查看特定服务的启动状态
[root@rockyser ~]# systemctl status nginx
#关键字搜索
[root@rockyser ~]# journalctl -b | grep 'error'
六、Rocky 10 vs Ubuntu 26.04 启动流程差异
| 对比项 | Rocky 10(RHEL 系) | Ubuntu 26.04(Debian 系) |
|---|---|---|
| GRUB 引导配置生成命令 | grub2-mkconfig -o /boot/grub2/grub.cfg |
update-grub |
| GRUB 最终配置文件路径 | /boot/grub2/grub.cfg |
/boot/grub/grub.cfg |
| 临时根镜像文件名 | initramfs-*.img |
initrd.img-* |
| 临时根镜像生成工具 | dracut |
update-initramfs |
| 进入单用户 / 救援模式参数 | rd.break / systemd.unit=rescue.target |
single / 1 |
| 默认启动目标 | multi-user.target(纯命令行服务器模式) |
graphical.target(图形桌面) |
| 内核软件包名称 | kernel |
linux-image |
| SELinux 安全模块 | 默认启用,需/.autorelabel重新打标签 |
默认关闭,无 SELinux |
| 系统包管理器 | dnf(RPM 包格式) | apt(deb 包格式) |
七、systemd服务管理
1、什么是systemd
Systemd 是 Linux 系统的初始化系统(init system)和服务管理器,PID 为 1,是系统中所有进程的父进程。
2、systemctl命令
常见命令
reload 和 restart 的区别:
reload :不中断服务,重新加载配置文件,适用于 Nginx、sshd 等支持热加载的服务
restart :先停止再启动,会中断服务
| 操作 | 命令 | 说明 |
|---|---|---|
| 启动 | systemctl start sshd |
立即启动 SSH 远程连接服务 |
| 停止 | systemctl stop sshd |
立即关闭 SSH,已登录会话会断开 |
| 重启 | systemctl restart sshd |
先停止再启动,所有 SSH 连接断开重连 |
| 重载配置 | systemctl reload sshd |
不踢现有连接,加载 sshd_config 新配置 |
| 查看状态 | systemctl status sshd |
查看运行状态、日志、监听端口 |
| 开机自启 | systemctl enable sshd |
创建软链接,开机自动启动 ssh 服务 |
| 禁用自启 | systemctl disable sshd |
删除自启链接,开机不自动启动 ssh |
| 检查是否启用 | systemctl is-enabled sshd |
返回 enabled /disabled |
| 开机自启并启动 | systemctl enable --now sshd |
一步开机自启并立即启动 |
| 开机不自启并关闭 | systemctl disable --now sshd |
一步开机不自启并立即关闭 |
enable 的原理
graph LR
A["/usr/lib/systemd/system/nginx.service"] -->|"systemctl enable"|
B["/etc/systemd/system/multi-user.target.wants/nginx.service"]
style A fill:#ccffff,stroke:#00aaaa,color:#2C3E50
style B fill:#ffffcc,stroke:#aaaa00,color:#2C3E50
systemctl enable 创建符号链接,系统启动时自动启动该服务
什么情况需要手动创建 service?
系统自带软件(sshd、nginx、firewalld、mysqld)安装包时会自动生成 .service 单元文件,无需手动创建;
只有程序没有官方配套 systemd 单元、或官方单元不满足业务需求时,才手动写 service。
3、演示手动创建service
安装JDK25
#rocky
[root@rockyser ~]# dnf install -y java-25-openjdk-headless
#Ubuntu
root@ubt2604ser:~# apt install -y openjdk-25-jdk-headless
[root@rockyser ~]# java -version
openjdk version "25.0.4" 2026-07-21 LTS
OpenJDK Runtime Environment (Red_Hat-25.0.4.0.7-1) (build 25.0.4+7-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-25.0.4.0.7-1) (build 25.0.4+7-LTS, mixed mode, sharing)
下载jenkins
#创建jenkins目录
[root@rockyser ~]# mkdir -p /opt/jenkins
# 下载 Jenkins WAR 包
[root@rockyser ~]# wget -O /opt/jenkins/jenkins.war https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war
#查看下载文件
[root@rockyser ~]# ls -l /opt/jenkins/
总计 98736
-rw-r--r--. 1 root root 101102833 7月 9日 23:42 jenkins.war
演示一:直接启动(java -jar)
Jenkins WAR 包可以直接用 java -jar 启动
#进入软件路径
[root@rockyser ~]# cd /opt/jenkins/
#启动
[root@rockyser jenkins]# java -jar jenkins.war
Running from: /opt/jenkins/jenkins.war
webroot: /root/.jenkins/war
2026-07-29 07:38:49.381+0000 [id=3] INFO winstone.Logger#logInternal: Beginning extraction from war file
2026-07-29 07:38:50.843+0000 [id=3] WARNING o.e.j.ee9.nested.ContextHandler#setContextPath: Empty contextPath
2026-07-29 07:38:51.079+0000 [id=3] INFO org.eclipse.jetty.server.Server#doStart: jetty-12.1.8; built: 2026-04-01T01:09:18.991Z; git: c9cdc9aaa434a3665b8a53b4d1cc3684992da649; jvm 25.0.4+7-LTS
2026-07-29 07:38:52.715+0000 [id=3] INFO o.e.j.e.w.StandardDescriptorProcessor#visitServlet: NO JSP Support for /, did not find org.eclipse.jetty.ee9.jsp.JettyJspServlet
2026-07-29 07:38:52.975+0000 [id=3] INFO o.e.j.s.DefaultSessionIdManager#doStart: Session workerName=node0
WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::objectFieldOffset has been called by com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider (file:/root/.jenkins/war/WEB-INF/lib/xstream-1.4.21.jar)
WARNING: Please consider reporting this to the maintainers of class com.thoughtworks.xstream.converters.reflection.SunUnsafeReflectionProvider
WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
2026-07-29 07:38:55.212+0000 [id=3] INFO hudson.WebAppMain#contextInitialized: Jenkins home directory: /root/.jenkins found at: $user.home/.jenkins
2026-07-29 07:38:55.800+0000 [id=3] INFO o.e.j.s.handler.ContextHandler#doStart: Started oeje9n.ContextHandler$CoreContextHandler@7a231dfd{Jenkins v2.568.1,/,b=file:///root/.jenkins/war/,a=AVAILABLE,h=oeje9n.ContextHandler$CoreContextHandler$CoreToNestedHandler@30814f43{STARTED}}
2026-07-29 07:38:55.861+0000 [id=3] INFO o.e.j.server.AbstractConnector#doStart: Started oejs.ServerConnector@4a05d8ae{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2026-07-29 07:38:55.870+0000 [id=3] INFO org.eclipse.jetty.server.Server#doStart: Started oejs.Server@4eb30d44{STARTING}[12.1.8,sto=0] @4801ms
2026-07-29 07:38:55.883+0000 [id=28] INFO winstone.Logger#logInternal: Winstone Servlet Engine running: controlPort=disabled
2026-07-29 07:38:56.372+0000 [id=27] INFO jenkins.model.Jenkins#<init>: Starting version 2.568.1
2026-07-29 07:38:56.811+0000 [id=37] INFO jenkins.InitReactorRunner$1#onAttained: Started initialization
2026-07-29 07:38:56.861+0000 [id=35] INFO jenkins.InitReactorRunner$1#onAttained: Listed all plugins
2026-07-29 07:39:01.467+0000 [id=35] INFO jenkins.InitReactorRunner$1#onAttained: Prepared all plugins
2026-07-29 07:39:01.490+0000 [id=37] INFO jenkins.InitReactorRunner$1#onAttained: Started all plugins
2026-07-29 07:39:01.496+0000 [id=37] INFO jenkins.InitReactorRunner$1#onAttained: Augmented all extensions
2026-07-29 07:39:02.322+0000 [id=38] INFO jenkins.InitReactorRunner$1#onAttained: System config loaded
2026-07-29 07:39:02.326+0000 [id=38] INFO jenkins.InitReactorRunner$1#onAttained: System config adapted
2026-07-29 07:39:02.331+0000 [id=38] INFO jenkins.InitReactorRunner$1#onAttained: Loaded all jobs
2026-07-29 07:39:02.341+0000 [id=35] INFO jenkins.InitReactorRunner$1#onAttained: Configuration for all jobs updated
2026-07-29 07:39:02.794+0000 [id=52] INFO hudson.util.Retrier#start: Attempt #1 to do the action check updates server
2026-07-29 07:39:04.281+0000 [id=37] INFO jenkins.install.SetupWizard#init:
[LF]>
[LF]> *************************************************************
[LF]> *************************************************************
[LF]> *************************************************************
[LF]>
[LF]> Jenkins initial setup is required. An admin user has been created and a password generated.
[LF]> Please use the following password to proceed to installation:
[LF]>
[LF]> 5c0cad51e60d42fc99bb31247346846a #默认密码
[LF]>
[LF]> This may also be found at: /root/.jenkins/secrets/initialAdminPassword #默认密码存放文件
[LF]>
[LF]> *************************************************************
[LF]> *************************************************************
[LF]> *************************************************************
#启动后浏览器http://IP地址:8080
#如果访问不通放开防火墙端口号
[root@rockyser ~]# firewall-cmd --permanent --add-port=8080/tcp
[root@rockyser ~]# firewall-cmd --reload

演示二 使用systemd
#创建服务文件
[root@rockyser ~]# vim /etc/systemd/system/jenkins.service
[root@rockyser ~]# cat /etc/systemd/system/jenkins.service
[Unit]
Description=Jenkins Continuous Integration Server
After=network.target
[Service]
Type=simple
User=root
Group=root
WorkingDirectory=/opt/jenkins
ExecStart=/usr/bin/java -jar /opt/jenkins/jenkins.war
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
| 配置项 | 取值 | 含义 |
|---|---|---|
| Description | Jenkins Continuous Integration Server | 服务描述,systemctl status 时展示 |
| After | network.target | 等待网络服务启动完成后,再启动 Jenkins;仅控制启动顺序,无强制依赖 |
| 配置项 | 取值 | 含义 |
|---|---|---|
| Type | simple | 进程类型:主程序前台持续运行(java -jar 适配 simple) |
| User | root | 运行该服务的操作系统用户 |
| Group | root | 运行该服务的用户组 |
| WorkingDirectory | /opt/jenkins | 程序工作目录,日志、相对路径文件以此为基准 |
| ExecStart | /usr/bin/java -jar /opt/jenkins/jenkins.war | 服务启动命令,只能写前台运行程序,不能后台 & |
| Restart | on-failure | 重启策略:仅进程异常崩溃、非人为 stop 时自动重启 |
| RestartSec | 10 | 进程崩溃后,延迟 10 秒再重新拉起服务 |
| 配置项 | 取值 | 含义 |
|---|---|---|
| WantedBy | multi-user.target | 自启挂靠目标;执行systemctl enable时,会在multi-user.target.wants生成软链接,多用户字符模式开机自动启动 |
#验证
#重新加载systemd配置(任何系统层面的修改都必须执行)
[root@rockyser ~]# systemctl daemon-reload
#启动/查看/开机自启动
[root@rockyser ~]# systemctl start jenkins.service
[root@rockyser ~]# systemctl enable jenkins.service
Created symlink '/etc/systemd/system/multi-user.target.wants/jenkins.service' → '/etc/systemd/system/jenkins.service'.
[root@rockyser ~]# systemctl status jenkins.service
● jenkins.service - Jenkins Continuous Integration Server
Loaded: loaded (/etc/systemd/system/jenkins.service; enabled; preset: disabled)
Active: active (running) since Wed 2026-07-29 16:00:43 CST; 24s ago
Invocation: 9da98ee00bdd46b48d800991490795b2
Main PID: 3683 (java)
Tasks: 41 (limit: 10329)
Memory: 177.7M (peak: 178.3M)
CPU: 16.100s
CGroup: /system.slice/jenkins.service
└─3683 /usr/bin/java -jar /opt/jenkins/jenkins.war
7月 29 16:00:51 rockyser java[3683]: [LF]> Jenkins initial setup is required. An admin user has been crea>
7月 29 16:00:51 rockyser java[3683]: [LF]> Please use the following password to proceed to installation:
7月 29 16:00:51 rockyser java[3683]: [LF]>
7月 29 16:00:51 rockyser java[3683]: [LF]> 5c0cad51e60d42fc99bb31247346846a
7月 29 16:00:51 rockyser java[3683]: [LF]>
7月 29 16:00:51 rockyser java[3683]: [LF]> This may also be found at: /root/.jenkins/secrets/initialAdmin>
7月 29 16:00:51 rockyser java[3683]: [LF]>
7月 29 16:00:51 rockyser java[3683]: [LF]> *************************************************************
7月 29 16:00:51 rockyser java[3683]: [LF]> *************************************************************
7月 29 16:00:51 rockyser java[3683]: [LF]> *************************************************************
[root@rockyser ~]#

八、journalctl 日志查看
1、为什么使用journalctl
传统 Linux 日志:syslog(rsyslog/syslog-ng)把日志分散存到 /var/log/ 一堆文件(syslog、auth.log、dmesg、kern.log、nginx 日志等),缺点:
日志文件杂乱,系统 / 内核 / 服务 / 开机日志分开存放;
无统一索引,过滤、按时间、按进程查询极麻烦;
无日志持久化、轮转、权限、日志等级统一管理;
容器、systemd 服务日志散落在各处,很难统一排查。
systemd 引入 journald 日志服务,所有日志统一由 journald 收集,journalctl 是唯一查询工具,现代 Ubuntu 16.04+/Debian/CentOS/Rocky/麒麟都默认搭载。
2、基础用法
查看服务日志
# 查看 jenkins 服务的全部日志
[root@rockyser ~]# journalctl -u jenkins.service
# 查看 jenkins 服务最近20行日志
[root@rockyser ~]# journalctl -u jenkins.service -n 20
7月 29 16:00:51 rockyser java[3683]: 2026-07-29 08:00:51.422+0000 [id=36] INFO jenkins.Init>
7月
#实时跟踪(最常用,类似 tail -f)
[root@rockyser ~]# journalctl -u jenkins.service -f
7月 29 16:00:51 rockyser java[3683]: [LF]>
7月 29 16:00:51 rockyser java[3683]: [LF]> 5c0cad51e60d42fc99bb31247346846a
按优先级过滤
#错误级别
[root@rockyser ~]# journalctl -u jenkins.service -p err
-- No entries --
#告警级别
[root@rockyser ~]# journalctl -u jenkins.service -p warning
-- No entries --
按时间查询
#组合起止时间
[root@rockyser ~]# journalctl -u jenkins.service --since "today" --until "now"
7月 29 16:00:43 rockyser systemd[1]: Started jenkins.service - Jenkins Continuous Integration Server.
#具体时间点
[root@rockyser ~]# journalctl -u jenkins.service --since "2026-7-29 16:30:33"
-- No entries --
[root@rockyser ~]# journalctl -u jenkins.service --since "2026-7-29"
7月 29 16:00:43 rockyser systemd[1]: Started jenkins.service - Jenkins Continuous Integration Server.
7月 29 16:00:43 rockyser java[3683]: Running from: /opt/jenkins/jenkins.war
#按相对时间
[root@rockyser ~]# journalctl -u jenkins.service --since "1 hour ago"
-- No entries --
3、字段过滤
按进程名(_COMM)
# 查看nginx进程的所有日志
[root@rockyser ~]# journalctl _COMM=nginx
7月 29 14:55:51 rockyser nginx[1104]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
7月 29 14:55:51 rockyser nginx[1104]: nginx: configuration file /etc/nginx/nginx.conf test is successful
# 查看java进程的日志(注意:会匹配所有 Java 应用)
[root@rockyser ~]# journalctl _COMM=java
7月 29 16:00:43 rockyser java[3683]: Running from: /opt/jenkins/jenkins.war
7月 29 16:00:43 rockyser java[3683]: webroot: /root/.jenkins/war
按完整路径过滤(_EXE)更精确
[root@rockyser ~]# which sshd
/usr/sbin/sshd
[root@rockyser ~]# journalctl _EXE=/usr/sbin/sshd
7月 29 14:55:50 rockyser sshd[1050]: Server listening on 0.0.0.0 port 22.
7月 29 14:55:50 rockyser sshd[1050]: Server listening on :: port 22.
按 PID 过滤(临时排查用)
[root@rockyser ~]# pstree -p | grep sshd
|-sshd(1050)-+-sshd-session(2336)---sshd-session(2358)---bash(2360)---su(2414)---bash(2418)-+-grep(4024)
[root@rockyser ~]# journalctl _PID=1050
7月 29 14:55:50 rockyser sshd[1050]: Server listening on 0.0.0.0 port 22.
7月 29 14:55:50 rockyser sshd[1050]: Server listening on :: port 22.
组合多个字段
[root@rockyser ~]# journalctl _COMM=sshd --since 'today'
7月 29 14:55:50 rockyser sshd[1050]: Server listening on 0.0.0.0 port 22.
7月 29 14:55:50 rockyser sshd[1050]: Server listening on :: port 22.
[root@rockyser ~]# journalctl _COMM=java --since "today"
7月 29 16:00:43 rockyser java[3683]: Running from: /opt/jenkins/jenkins.war
7月 29 16:00:43 rockyser java[3683]: webroot: /root/.jenkins/war
[root@rockyser ~]# journalctl _PID=3683 -p err
-- No entries --
查看所有可用的字段值
# 列出所有服务单元
[root@rockyser ~]# journalctl -F _SYSTEMD_UNIT
systemd-logind.service
vgauthd.service
# 列出所有曾记录过的进程名(用于确认正确的 _COMM 值)
[root@rockyser ~]# journalctl -F _COMM
systemd-logind
VGAuthService
4、日志存储管理
查看与清理日志
redhat:journald 日志默认存放在 /run/log/journal(tmpfs 内存文件系统)
下面删除命令不会删除活跃日志
#查看日志占用了多少磁盘空间
[root@rockyser ~]# journalctl --disk-usage
Archived and active journals take up 5.6M in the file system.
#清理到只剩 500M 日志
[root@rockyser ~]# journalctl --vacuum-size=500M
#清理到只保留最近 7 天
[root@rockyser ~]# journalctl --vacuum-time=7d
持久化保存journalctl日志
#Redhat系列需要手动开始日志持久化
#创建日志保存目录(只能是这个路径)
[root@rockyser ~]# mkdir -p /var/log/journal
#运行journalctl--flush命令,将当前日志刷新到存储中。如果systemd-journald服务成功刷新当前日志,则该服务将在/var/log/journal目录中创建子目录
[root@rockyser ~]# journalctl --flush
#查看日志存放路径是否生成
[root@rockyser ~]# ls /var/log/journal/
d4a3c4d8d6304ffa88b8b72f993813a0
[root@rockyser ~]# ls /var/log/journal/d4a3c4d8d6304ffa88b8b72f993813a0/
system@03b0fb6118104e308307b4be2ccc7300-0000000000000001-000657c90815781e.journal
system.journal
user-1000.journal
#Ubuntu:默认开启持久存储,安装系统自动创建 /var/log/journal
常见命令
# ═══════════════════════════════════════════════════════════
# 基础查询
# ═══════════════════════════════════════════════════════════
journalctl -u jenkins # 查看服务日志
journalctl -u jenkins -f # 实时跟踪
journalctl -u jenkins -n 100 # 最近 100 行
# ═══════════════════════════════════════════════════════════
# 过滤(精准定位)
# ═══════════════════════════════════════════════════════════
journalctl _COMM=sshd # 按进程名
journalctl _EXE=/usr/bin/java # 按完整路径
journalctl _PID=4709 # 按 PID
journalctl -u jenkins -p err # 只看错误
journalctl --since "1 hour ago" # 时间范围
# ═══════════════════════════════════════════════════════════
# 存储管理
# ═══════════════════════════════════════════════════════════
journalctl --disk-usage # 查看占用空间
journalctl --vacuum-size=500M # 清理到 500M
journalctl --vacuum-time=7d # 只保留 7 天
优先级参考
| 数值 | 名称 (关键字) | 英文全称 | 日志说明 |
|---|---|---|---|
| 0 | emerg | EMERG | 系统紧急崩溃,整机不可用 |
| 1 | alert | ALERT | 必须立刻修复的严重故障 |
| 2 | crit | CRIT | 严重错误,业务大面积受损 |
| 3 | err | ERR | 常规程序错误,局部功能异常 |
| 4 | warn | WARNING | 警告,暂时不影响运行,长期会出问题 |
| 5 | notice | NOTICE | 正常重要事件,非错误 |
| 6 | info | INFO | 常规运行信息(默认输出等级) |
| 7 | debug | DEBUG | 调试详细日志,开发排错用 |
九、定时任务
1、认识定时任务
运维工作中经常需要在固定时间执行某些任务:每天凌晨备份日志、每小时清理临时文件、每周一发送报表……这些重复性工作可以用定时任务自动完成。
定时方式:传统Cron与现代systemd timer
2、Cron定时任务
Cron 是 Linux 系统中最经典的定时任务工具,通过 crond 守护进程每分钟检查一次是否有任务需要执行。
时间字段格式
* * * * * 命令
┊ ┊ ┊ ┊ ┊
┊ ┊ ┊ ┊ └─── 星期几 (0-7, 0和7都表示周日)
┊ ┊ ┊ └───── 月份 (1-12)
┊ ┊ └─────── 日期 (1-31)
┊ └───────── 小时 (0-23)
└─────────── 分钟 (0-59)
特殊字符
| 符号 | 名称 | 作用说明 | 实操示例 |
|---|---|---|---|
* |
星号 | 匹配该字段所有取值,代表 “每一个” | */5 * * * * 每 5 分钟执行 |
, |
逗号 | 多时间点并列,多值分隔 | 0 2,4,6 * * * 凌晨 2、4、6 点执行 |
- |
减号 | 指定连续数值区间 | 0 9-18 * * * 9 点至 18 点整点执行 |
/ |
斜杠 | 步长间隔,搭配*/ 区间使用 |
0 1-23/2 * * * 每隔 2 小时执行 |
常见示例
# 每天凌晨 2:30 执行备份
30 2 * * * /usr/local/bin/mysql-full-backup.sh
# 每小时执行一次
0 * * * * /usr/local/bin/mysql-full-backup.sh
# 每周一凌晨 3:00 执行
0 3 * * 1 /usr/local/bin/mysql-full-backup.sh
# 每月1号凌晨 4:00 执行
0 4 1 * * /usr/local/bin/mysql-full-backup.sh
# 每 5 分钟执行一次
*/5 * * * * /usr/local/bin/mysql-full-backup.sh
Cron备份案例
#创建备份目录
[root@rockyser ~]# mkdir -p /backup
#创建备份脚本
[root@rockyser ~]# cat > "/backup/logs-backup.sh" << 'EOF'
#!/bin/bash
tar -cavf /backup/logs-backup-$(date +%F).tar.gz /var/log &>/backup/logs.txt
EOF
#增加执行权限
[root@rockyser ~]# chmod +x /backup/logs-backup.sh
#测试备份脚本
[root@rockyser ~]# /backup/logs-backup.sh
[root@rockyser ~]# ls /backup/
[root@rockyser ~]# cat /backup/logs.txt
#创建Cron定时任务每天凌晨12点执行
[root@rockyser ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@rockyser ~]# crontab -l
0 0 * * * /backup/logs-backup.sh
#模拟修改时间
[root@rockyser ~]# date -s "20260730 23:59:55"
2026年 07月 30日 星期四 23:59:55 CST
[root@rockyser ~]# ls /backup/
logs-backup-2026-07-30.tar.gz logs-backup.sh logs.txt
[root@rockyser ~]# date
2026年 07月 31日 星期五 00:00:11 CST
#验证备份
[root@rockyser ~]# ls /backup/
logs-backup-2026-07-30.tar.gz logs-backup-2026-07-31.tar.gz logs-backup.sh logs.txt
[root@rockyser ~]# cat /backup/logs.txt
/var/log/
/var/log/private/
/var/log/wtmp
/var/log/btmp
/var/log/lastlog
/var/log/samba/
/var/log/samba/old/
/var/log/audit/
/var/log/audit/audit.log
3、Systemd Timer计划任务
Systemd Timer 是 Systemd 内置的定时任务机制,由一个 .timer 单元(定义触发时间)和一个 .service 单元(定义执行内容)配对工作。
Timer触发方式
| 触发方式 | 说明 | 示例 |
|---|---|---|
| OnCalendar | 日历定点触发,兼容 Cron 定时语法,支持年月日时分秒 | OnCalendar=*-*-* 02:00:00 每天凌晨 2 点执行 |
| OnBootSec | 系统开机完成后,延迟指定时长触发一次 | OnBootSec=5min 开机 5 分钟后运行任务 |
| OnUnitActiveSec | 对应 service 上一次执行完成后,间隔指定时长循环触发 | OnUnitActiveSec=1h 每间隔 1 小时重复执行 |
| 触发字段 | 作用说明 | 实操示例 |
|---|---|---|
| OnStartupSec | systemd 自身启动完成后延迟触发 | OnStartupSec=30s |
| OnUnitInactiveSec | service 停止后,等待指定时长再触发 | OnUnitInactiveSec=10min |
| OnActiveSec | timer 自身启动后,延迟时长触发一次 | OnActiveSec=2min |
Timer实战
#创建备份脚本
[root@rockyser ~]# cat > /backup/backup-log.sh << 'EOF'
> #!/bin/bash
/usr/bin/tar -czf /backup/logs-timer-$(date +%F).tar.gz /var/log/ 2>/dev/null
EOF
#增加权限
[root@rockyser ~]# chmod +x /backup/backup-log.sh
#创建systemd服务
[root@rockyser ~]# cat > /etc/systemd/system/backup-log.service << 'EOF'
[Unit]
Description=Log Backup Service (Timer)
[Service]
Type=oneshot
ExecStart=/backup/backup-log.sh
User=root
EOF
#创建Timer计划任务
[root@rockyser ~]# cat > /etc/systemd/system/backup-log.timer << 'EOF'
[Unit]
Description=Log Backup Timer
[Timer]
OnCalendar=daily
Persistent=true
Unit=backup-log.service
[Install]
WantedBy=timers.target
#重新加载systemd,并设置开机自启动
[root@rockyser ~]# systemctl daemon-reload
[root@rockyser ~]# systemctl enable --now backup-log.timer
Created symlink '/etc/systemd/system/timers.target.wants/backup-log.timer' → '/etc/systemd/system/backu p-log.timer'.
#查看激活的计划任务
[root@rockyser ~]# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2026-07-31 01:50:58 CST 1h 26min Thu 2026-07-30 23:59:55 CST 24min ago dnf-makecache.timer dnf-makecache.service
Fri 2026-07-31 23:34:48 CST 23h Thu 2026-07-30 09:27:38 CST 49min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Sat 2026-08-01 00:00:00 CST 23h Fri 2026-07-31 00:11:34 CST - backup-log.timer backup-log.service
Sat 2026-08-01 00:15:47 CST 23h Fri 2026-07-31 00:11:34 CST 12min ago logrotate.timer logrotate.service
Sat 2026-08-01 00:59:26 CST 24h Fri 2026-07-31 00:17:51 CST 6min ago plocate-updatedb.timer plocate-updatedb.service
Sun 2026-08-02 01:00:00 CST 2 days Thu 2026-07-30 09:12:36 CST 1h 4min ago raid-check.timer raid-check.service
Mon 2026-08-03 00:56:51 CST 3 days Thu 2026-07-30 09:36:36 CST 40min ago fstrim.timer fstrim.service
7 timers listed.
Pass --all to see loaded but inactive timers, too.
#测试任务,如果提示开启失败临时关闭SELinux安全模块:setenforce 0
[root@rockyser ~]# systemctl start backup-log.service
Job for backup-log.service failed because the control process exited with error code.
See "systemctl status backup-log.service" and "journalctl -xeu backup-log.service" for details.
[root@rockyser ~]# setenforce 0
[root@rockyser ~]# systemctl start backup-log.service
#查看备份日志和文件
[root@rockyser ~]# journalctl -u backup-log.service -n 20
7月 31 00:31:18 rockyser systemd[1]: Starting backup-log.service - Log Backup Service (Timer)...
7月 31 00:31:18 rockyser systemd[1]: backup-log.service: Deactivated successfully.
7月 31 00:31:18 rockyser systemd[1]: Finished backup-log.service - Log Backup Service (Timer).
[root@rockyser ~]# ls -l /backup/
总计 928
-rwxr-xr-x. 1 root root 90 7月31日 00:07 backup-log.sh
-rw-r--r--. 1 root root 943366 7月31日 00:31 logs-timer-2026-07-31.tar.gz
| 字段名 | 核心作用 | 详细说明 |
|---|---|---|
Description |
单元可读描述 | 仅用于标识定时器功能,无实际执行逻辑,会在systemctl status/list-timers中展示,方便运维识别 |
OnCalendar |
日历式定时触发 | 定义定点执行时间,兼容 Cron 语法,是最常用的定时规则;支持简写、完整表达式两种写法 |
Persistent |
关机漏执行补跑 | 服务器关机 / 休眠时错过的定时任务,开机后自动补执行 1 次,避免因停机导致任务遗漏,生产备份场景刚需 |
Unit |
绑定执行服务 | 必填核心字段,指定定时器触发时,要启动的.service服务文件名,必须和同目录下的服务文件完全一致 |
WantedBy |
开机自启挂载 | 定义定时器的开机自启依赖,指定要挂载到的系统目标单元;timers.target是系统定时器总目标,实现开机自动启用该定时器 |
其他常见字段
| 字段名 | 核心作用 | 适用场景 | 示例 |
|---|---|---|---|
OnBootSec |
系统开机后延迟触发 | 开机后执行初始化任务、延迟启动的定时 | OnBootSec=5min 开机 5 分钟后执行 |
OnUnitActiveSec |
服务执行完成后循环触发 | 固定间隔重复执行的任务(如每小时同步一次) | OnUnitActiveSec=1h 上一次执行完后,间隔 1 小时再跑 |
RandomizedDelaySec |
随机延迟偏移 | 多台服务器同定时任务,避免同一时间并发压垮业务 | RandomizedDelaySec=300 随机 0~5 分钟偏移 |
Accumulate |
错过任务是否堆积执行 | 避免关机错过多次任务,开机后一次性执行多次 | Accumulate=no 仅补执行最近 1 次错过的任务 |
Restart |
任务失败自动重试 | 服务执行失败后,自动重启重试 | Restart=on-failure 失败时重试 |
4、OnCalendar 时间表达式
| 表达式 | 含义 |
|---|---|
| daily | 每天 00:00:00 |
| weekly | 每周一 00:00:00 |
| monthly | 每月 1 号 00:00:00 |
| hourly | 每小时整点 |
| boot | 系统启动时 |
| –* 02:00:00 | 每天凌晨 2 点 |
| Mon…Fri 09:00:00 | 工作日上午 9 点 |
| --01 04:00:00 | 每月 1 号凌晨 4 点 |
5、Rocky vs Ubuntu 差异
rocky:服务名 crond、看日志方式 /var/log/syslog(grep cron)
Ubuntu:服务名 cron、查看日志方式 /var/log/cron
十、动手尝试****
1 完成每日凌晨1点定时打包/var/log/message文件的定时任务
2 完成每半小时自动创建一个文件并且删除完成日志记录的定时任务方式自定义
#1 完成每日凌晨1点定时打包/var/log/message文件的定时任务
#创建备份目录
[root@rockyser ~]# cd /backup/
[root@rockyser backup]# ls
backup-log.sh logs-timer-2026-07-31.tar.gz
#创建脚本
[root@rockyser backup]# cat > messlog-backup.sh << 'EOF'
#!/bin/bash
tar -czf /backup/messlog-backup-$(date +%F).tar.gz /var/log/message >/backup/messback.log 2>/dev/null
EOF
#附加执行权限
[root@rockyser backup]# chmod +x messlog-backup.sh
[root@rockyser backup]# ll messlog-backup.sh
-rwxr-xr-x. 1 root root 97 7月31日 01:03 messlog-backup.sh
#制作定时任务
[root@rockyser backup]# crontab -e
crontab: installing new crontab
Backup of root's previous crontab saved to /root/.cache/crontab/crontab.bak
[root@rockyser backup]# crontab -l
0 1 * * * /backup/messlog-backup.sh
#手动测试运行
[root@rockyser backup]# ./messlog-backup.sh
[root@rockyser backup]# ll
总计 936
-rwxr-xr-x. 1 root root 90 7月31日 00:07 backup-log.sh
-rw-r--r--. 1 root root 943366 7月31日 00:31 logs-timer-2026-07-31.tar.gz
-rw-r--r--. 1 root root 0 7月31日 01:10 messback.log
-rw-r--r--. 1 root root 45 7月31日 01:10 messlog-backup-2026-07-31.tar.gz
-rwxr-xr-x. 1 root root 114 7月31日 01:10 messlog-backup.sh
#2 完成每半小时自动创建一个文件并且删除完成日志记录的定时任务
#创建脚本和附加权限
[root@rockyser backup]# cat > chuangjiangfile.sh << 'EOF'
#!/bin/bash
find /backup/ -type f -name "*.log" -mtime -1 |xargs rm -rf
touch file-$(date +%H%M) &>touckfile.log
EOF
[root@rockyser backup]# chmod +x chuangjiangfile.sh
#试运行
[root@rockyser backup]# ./chuangjiangfile.sh
[root@rockyser backup]# ls
chuangjiangfile.sh file-0227 touckfile.log
#创建定时任务
[root@rockyser backup]# crontab -e
crontab: installing new crontab
Backup of root's previous crontab saved to /root/.cache/crontab/crontab.bak
[root@rockyser backup]# crontab -l
0 1 * * * /backup/messlog-backup.sh
*/30 * * * * /backup/chuangjiangfile.sh
90 7月31日 00:07 backup-log.sh
-rw-r–r–. 1 root root 943366 7月31日 00:31 logs-timer-2026-07-31.tar.gz
-rw-r–r–. 1 root root 0 7月31日 01:10 messback.log
-rw-r–r–. 1 root root 45 7月31日 01:10 messlog-backup-2026-07-31.tar.gz
-rwxr-xr-x. 1 root root 114 7月31日 01:10 messlog-backup.sh
#2 完成每半小时自动创建一个文件并且删除完成日志记录的定时任务
#创建脚本和附加权限
[root@rockyser backup]# cat > chuangjiangfile.sh << ‘EOF’
#!/bin/bash
find /backup/ -type f -name “*.log” -mtime -1 |xargs rm -rf
touch file-$(date +%H%M) &>touckfile.log
EOF
[root@rockyser backup]# chmod +x chuangjiangfile.sh
#试运行
[root@rockyser backup]# ./chuangjiangfile.sh
[root@rockyser backup]# ls
chuangjiangfile.sh file-0227 touckfile.log
#创建定时任务
[root@rockyser backup]# crontab -e
crontab: installing new crontab
Backup of root’s previous crontab saved to /root/.cache/crontab/crontab.bak
[root@rockyser backup]# crontab -l
0 1 * * * /backup/messlog-backup.sh
*/30 * * * * /backup/chuangjiangfile.sh
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)