一、进程和内存管理

内核作用:进程管理、内存管理、文件管理、驱动管理、网络管理等

1.1 什么是进程

Process:运行中的程序的一个副本,是被载入内存的一个指令集合,是资源分配的单位

  • 进程 ID 用来标记各个进程
  • UID、GID 和SELinux语境决定对文件系统的存取和访问权限
  • 通常从执行进程的用户来继承
  • 存在声明周期

进程的创建:

  • init:第一个进程,Centos7 之后为 systemd
  • 进程:由父进程创建,fork() 出子进程,使用写时复制机制

1.2 进程、线程和携程

1.2.1 进程

进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

进程一般由程序、数据集合和程序控制块三部分组成

  • 程序用于描述进程要完成的功能,是控制进程执行的指令集
  • 数据集合是程序在执行时所需要的数据和工作区
  • 程序控制块(PCB),包含进程的描述信息和控制信息,是进程存在的唯一标志

进程具有的特征

  • 动态性:进程是程序的一次执行过程,是临时的,有生命周期的,是动态产生的,动态消亡的
  • 并发性:任何进程都可以和其它进程一起并发执行
  • 独立性:进程是系统进行资源分配和调度的一个独立单位
  • 结构性:进程由程序、数据和进程控制块三部分组成

1.2.2 线程

在操作系统早期没有现成的概念,进程是拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。

之后随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销太大,无法满足越来越复杂的程序的要求,便出现了线程。

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单位,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(即所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。

1.2.3 协程

协程是一种基于线程之上,但比线程更加轻量级的存在,这种由程序员自己来管理的轻量级线程叫做——用户空间线程,具有对内核不可见的特性。

协程的特点

  • 线程的切换由操作系统负责调度,携程由用户自己进行调度,因此减少了上下文切换,提高了效率
  • 线程的默认stack大小为1M,而协程更轻量,接近1K。因此可以在相同的内存中开启更多的协程
  • 由于同一个线程上,因此可以避免竞争关系而使用锁
  • 适用于被阻塞且需要大量并发的场景,但不适用于大量计算的多线程

进程与线程的区别

  • 进程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
  • 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
  • 进程之间相互隔离,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级别的资源(如打开的文件和信号),某进程内的线程在其它进程不可见
  • 线程的上下文切换比进程的上下文切换要快得多

Question: 如何查看进程中的线程:question:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1、pstree 命令,有{}的表示是该进程的线程
# 数字表示开启的线程的个数,也可加 -p 选项查看详细信息
[root@wh-ctyun ~]# pstree
systemd─┬─NetworkManager─┬─dhclient
│ └─2*[{NetworkManager}]
├─auditd───{auditd}
├─crond
├─dbus-daemon
├─gssproxy───5*[{gssproxy}]
├─haproxy-systemd───haproxy───haproxy
├─login───bash
├─master─┬─pickup
│ └─qmgr
├─mysqld_safe───mysqld───18*[{mysqld}]
├─polkitd───6*[{polkitd}]
├─qemu-ga
├─redis-server───2*[{redis-server}]
├─rpcbind
├─rsyslogd───3*[{rsyslogd}]
├─sshd───sshd───bash───pstree
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
└─wrapper─┬─java───13*[{java}]
└─{wrapper}

2、直接查看指定进程的文件
# 格式 grep -i threads /proc/PID/status
[root@wh-ctyun ~]# grep -i threads /proc/654/status
Threads: 14

1.3 进程优先级

image-20221202090922512

二、进程管理和性能相关工具

2.1 进程树 pstree

pstree 用来显示进程的父子关系,以树型结构显示

1
2
3
4
5
6
7
pstree [option] [PID | USER]

options:
-p 显示PID
-T 不显示线程thread,默认显示线程
-u 显示用户切换
-H pid 高亮显示指定进程及前辈进程

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
[root@Rocky8-mini ~]# pstree
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─VGAuthService
├─agetty
├─auditd───{auditd}
├─chronyd
├─crond
├─dbus-daemon
├─irqbalance───{irqbalance}
├─polkitd───5*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─sshd───sshd───sshd───bash───pstree
├─sssd─┬─sssd_be
│ └─sssd_nss
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───5*[{tuned}]
└─vmtoolsd───2*[{vmtoolsd}]

[root@Rocky8-mini ~]# su wh
[wh@Rocky8-mini root]$ pstree -u
systemd─┬─NetworkManager───2*[{NetworkManager}]
├─VGAuthService
├─agetty
├─auditd───{auditd}
├─chronyd(chrony)
├─crond
├─dbus-daemon(dbus)
├─irqbalance───{irqbalance}
├─polkitd(polkitd)───5*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
├─sshd───sshd───sshd───bash───su───bash(wh)───pstree
├─sssd─┬─sssd_be
│ └─sssd_nss
├─systemd───(sd-pam)
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───5*[{tuned}]
└─vmtoolsd───2*[{vmtoolsd}]

2.2 进程信息 ps

ps 可以查看进程当前状态的信息,默认显示当前终端中的进程信息,Linux系统各进程的相关信息均保存在/proc/PID目录下的各文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ps [option] ...

options:
a 显示所有终端中的进程
x 包括不链接终端中的进程
u 显示进程所有者的信息
f 显示进程树,相当于 --forest
k|--sort 属性 对属性排序,属性前加 - 表示倒序
o 属性... 指定显示的信息,如 pid、cmd、%cpu、%mem
L 显示支持的属性列表
-C cmdlist 指定命令,多个命令用','分隔
-L 显示线程
-e 显示所有进程,相当于-A
-f 显示完整格式程序信息
-F 显示更完整格式的进程信息
-H 以进程层级格式显示进程相关信息
-u userlist 指定有效的用户ID或名称
-U userlist 指定真正的用户ID或名称
-g gid或groupname 指定有效的gid或组名称
-G gid或groupname 指定真正的gid或组名称
-p pid 显示指定的pid的进程
--ppid pid 指定父进程的PID,显示属于父进程的子进程
-t ttylist 指定tty,相当于 t
-M 显示selinux信息,相当于Z

ps 输出属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
C: ps -ef  显示列C表示cpu的利用率
VSZ: 虚拟内存集,线性内存
RSS: 常驻内存集
STAT: 进程状态
R: running
S: interruptable sleeping
D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前台进程
l: 多线程进程
L: 内存分页并带锁
N: 低优先级进程
<: 高优先级进程
s: session leader,会话发起者
I: Idle kernel thread, Centos8 新特性
ni: nice
pri: priority
rtprio: 实时优先级
psr: processor CPU编号

2.3 查看进程信息 prtstat

显示进程信息,来自于psmisc包

1
2
prtstat [options] PID
-r raw格式显示

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@Rocky8-mini ~]# prtstat -r 1846 
pid: 1846 comm: bash
state: S ppid: 1845
pgrp: 1846 session: 1846
tty_nr: 34816 tpgid: 1875
flags: 404000 minflt: 1473
cminflt: 3065 majflt: 0
cmajflt: 5 utime: 0
stime: 2 cutime: 0
cstime: 2 priority: 20
nice: 0 num_threads: 1
itrealvalue: 0 starttime: 3410389
vsize: 27787264 rss: 1227
rsslim: 18446744073709551615 startcode: 94493703389184
endcode: 94493704468816 startstack: 140723809939296
kstkesp: 0 kstkeip: 0
wchan: 0 nswap: 0
cnswap: 0 exit_signal: 17
processor: 1 rt_priority: 0
policy: 0 delayaccr_blkio_ticks: 0
guest_time: 0 cguest_time: 0

2.4 设置和调整进程优先级

进程优先级调整

  • 静态优先级
  • 进程默认启动时的nice值为0,优先级为120
  • 只有根用户才能降低nice值(提高优先性)

nice 命令:以指定的优先级来启动进程

1
2
nice [OPTION] [COMMAND [ARG]...]
-n, --adjustment=N add integer N to the niceness (default 10)

renice 命令:调整正在执行中的进程的优先级

1
renice [-n] priority pid ...

查看

1
ps axo pid,comm,ni

示例

1
2
3
4
5
6
7
8
9
10
[root@Rocky8-mini ~]# nice -n -10 ping www.baidu.com
[root@Rocky8-mini ~]# ps axo pid,cmd,nice | grep ping
1944 ping www.baidu.com -10
1946 grep --color=auto ping 0

[root@Rocky8-mini ~]# renice -n -20 1944
1944 (process ID) old priority -10, new priority -20
[root@Rocky8-mini ~]# ps axo pid,cmd,nice | grep ping
1944 ping www.baidu.com -20
1950 grep --color=auto ping 0

2.5 搜索进程

按条件搜索进程

1
2
3
(1) ps 选项 | grep 'PATTERN'
(2) pgrep 按预定义模式
(3) /sbin/pidof 按确切的程序名称查看pid

2.5.1 pgrep

格式

1
2
3
4
5
6
7
8
9
10
11
pgrep [options] pattern

[options]
-u uid: effective user
-U uid: real user, 真正运行命令的发起者
-t terminal: 与指定终端相关的进程
-l: 显示进程名
-a: 显示完整格式的进程名
-P pid: 显示指定进程的子进程

pkill [options] pattern 杀死某个进程

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@Rocky8-mini ~]# pgrep -l -u  wh
1993 bash
2020 ping

[root@Rocky8-mini ~]# pgrep -aP 1993
2020 ping www.baidu.com

[root@Rocky8-mini ~]# pgrep -at pts/1
1913 -bash
1992 su wh
1993 bash
2020 ping www.baidu.com

# 杀死c1这个用户的进程
pkill -u c1

2.5.2 pidof

格式

1
2
pidof [options] [program [...]]
-x 按脚本名称查找pid

示例

1
2
[root@Rocky8-mini ~]# pidof bash
2034 1993 1913 1846

2.6 负载查询 uptime

/proc/uptime 包括两个值,单位 s

  • 系统启动时长
  • 空闲进程的总时长(按总的CPU核数计算)

uptime 和 w 显示以下内容

  • 当前时间
  • 系统已启动的时间
  • 当前上线人数
  • 系统平均负载(1、5、15分钟的平均负载,一般不会超过1,超过5时建议警报)

系统平均负载:指在特定时间间隔内运行队列中的平均进程数,通常每个CPU内核的当前活动进程数不大于3,那么系统的性能良好。如果每个CPU内核的任务数大于5,那么此主机的性能有严重问题。

如:Linux主机是一个双核CPU,当 load average 为 6 的时候说明机器已经被充分使用

示例

1
2
3
4
5
6
7
8
[root@Rocky8-mini ~]# uptime
09:49:24 up 10:06, 3 users, load average: 0.00, 0.00, 0.00
[root@Rocky8-mini ~]# w
09:49:29 up 10:06, 3 users, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 192.168.119.1 09:11 1.00s 0.10s 0.00s w
root pts/1 192.168.119.1 09:19 13:58 0.06s 0.02s bash
root pts/2 192.168.119.1 09:38 7:45 0.03s 0.03s -bash

2.7 显示CPU相关统计 mpstat

来源sysstat包

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@Rocky8-mini ~]# dnf -y install sysstat

[root@Rocky8-mini ~]# mpstat
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/07/2022 _x86_64_ (2 CPU)

08:40:05 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
08:40:05 AM all 0.01 0.00 0.07 0.00 0.04 0.04 0.00 0.00 0.00 99.84

# 每1秒显示一次结果,总共3次
[root@Rocky8-mini ~]# mpstat 1 3
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/07/2022 _x86_64_ (2 CPU)

08:41:28 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
08:41:29 AM all 4.10 0.00 13.11 0.00 0.00 0.82 0.00 0.00 0.00 81.97
08:41:30 AM all 6.11 0.00 17.56 0.00 0.00 0.00 0.00 0.00 0.00 76.34
08:41:31 AM all 4.17 0.00 12.50 0.00 0.00 0.00 0.00 0.00 0.00 83.33
Average: all 4.83 0.00 14.48 0.00 0.00 0.27 0.00 0.00 0.00 80.43

2.8 查看进程实时状态 top 和 htop

2.8.1 top

top 提供动态的实时进程状态

top 提供的内置命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
帮助: h 或 ?, 按 q 或 esc 退出帮助

排序
P: 以占据的CPU百分比, %CPU
M: 以内存占据的百分比, %MEM
T: CPU累积占用时长, TIME+

首部信息显示
uptime 信息: l命令
tasks及CPU信息: t命令
CPU分别显示: 数字 1
memory信息: m命令

退出命令: q
修改刷新时间间隔: s
终止指定进程: k

top 展示的信息详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@Rocky8-mini ~]# top
# 当前top命令运行的时间 已经运行的时长 当前用户登录数 系统的负载均衡平均值: 最近1分钟 5分钟 15分钟
top - 08:45:17 up 12:56, 2 users, load average: 0.09, 0.07, 0.02

# 当前系统总共的进程数 正在运行的进程数量 处于睡眠状态的 处于停止状态 处于僵死状态
Tasks: 156 total, 1 running, 155 sleeping, 0 stopped, 0 zombie

# us:用户空间占用CPU百分比(Host.cpu.user)
# sy:内核空间占用CPU百分比(Host.cpu.system)
# ni:用户进程空间内改变过优先级的进程占用CPU百分比
# id:空闲CPU百分比(Host.cpu.idle)
# wa:等待输入输出的CPU时间百分比
# hi:硬件中断
# si:软件中断
# st:实时
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.2 si, 0.0 st

# 总内存 空闲的内存 已使用的内存空间 缓冲区和缓存使用的空间
MiB Mem : 1790.3 total, 1156.8 free, 222.1 used, 411.4 buff/cache
# 总的交换空间 空闲的 已使用的 用于内核缓存的
MiB Swap: 2048.0 total, 2048.0 free, 0.0 used. 1405.3 avail Mem

# PID 进程号
# USER 用户
# PR 优先级
# NI NICE值
# VIRT 虚拟内存集
# RES 常驻内存集
# SHR 共享内存大小
# S 状态
# %CPU CPU的占据百分比
# %MEM 内存的占用百分比
# TIME+ 累计运行时长
# COMMAND 启动此进程的命令
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

top 选项

1
2
3
4
5
-d #: 指定刷新时间间隔,默认为3秒;
-b: 以批次方式;
-n #: 显示多少批次;
-u: 只显示指定的进程
-H: 线程模式

示例

1
top -H -P `pidof mysqld`

2.8.2 htop

选项

1
2
3
-d #: 指定延迟时间
-u UserName: 仅显示指定用户的进程
-s COLOMN: 以指定字段进行排序

子命令

1
2
3
4
s: 跟踪选定进程的系统调用;
l: 显示选定进程打开的文件列表;
a:将选定的进程绑定至某指定CPU核心;
t: 显示进程树

来自于epel源

1
[root@Rocky8-mini ~]# dnf -y install htop &> /dev/null;htop

image-20221207224113036

2.9 内存空间 free

free 可以显示内存空间使用状态

格式:

1
2
3
4
5
6
7
8
9
10
11
free [option]

常用选项
-b 以Byte为单位
-m 以MB为单位
-g 以GB为单位
-h 易读格式
-o 不显示-/+buffers/cache行
-t 显示 RAM+swap 的总和
-s n 刷新间隔为n秒
-C n 刷新n次后即退出

示例:

1
2
3
4
5
6
7
8
[root@Rocky8-mini ~]# free
total used free shared buff/cache available
Mem: 1833232 224152 1306820 8900 302260 1448232
Swap: 2097148 0 2097148
[root@Rocky8-mini ~]# free -h
total used free shared buff/cache available
Mem: 1.7Gi 218Mi 1.2Gi 8.0Mi 295Mi 1.4Gi
Swap: 2.0Gi 0B 2.0Gi

关于缓存的清理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@Rocky8-mini ~]# man proc
···
/proc/sys/vm/drop_caches (since Linux 2.6.16)
Writing to this file causes the kernel to drop clean caches, dentries, and
inodes from memory, causing that memory to become free. This can be useful for
memory management testing and performing reproducible filesystem
benchmarks.Because writing to this file causes the benefits of caching to be
lost, it can degrade overall system performance.
To free pagecache, use:
echo 1 > /proc/sys/vm/drop_caches
To free dentries and inodes, use:
echo 2 > /proc/sys/vm/drop_caches
To free pagecache, dentries and inodes, use:
echo 3 > /proc/sys/vm/drop_caches
Because writing to this file is a nondestructive operation and dirty objects
are not freeable, the user should run sync(1) first.

2.10 进程对应的内存映射 pmap

格式

1
2
3
4
5
6
pmap [options] pid [...]
-x: 显示详细格式信息

[root@Rocky8-mini ~]# pmap 1
# cat /proc/PID/maps
[root@Rocky8-mini ~]# cat /proc/1/maps

示例:关于系统调用和库调用的命令

1
2
3
4
5
6
7
# 查看系统调用
[root@Rocky8-mini ~]# dnf -y install strace
[root@Rocky8-mini ~]# strace ls

# 查看库调用
[root@Rocky8-mini ~]# dnf -y install ltrace
[root@Rocky8-mini ~]# ltrace ls

2.11 虚拟内存信息 vmstat

格式

1
2
vmstat [options] [delay [count]]
-s 显示内存的统计数据

vmstat 显示项说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
procs:
r: 可运行(正运行或等待运行)进程的个数,和核心数有关
b: 处于不可中断睡眠态的进程个数(被阻塞的队列的长度)

memory:
swapd: 交换内存的使用总量
free: 空闲物理内存总量
buffer: 用于buffer的内存总量
cache: 用于cache的内存总量

swap:
si: 从磁盘交换进内存的数据速率(kb/s)
so: 从内存交换至磁盘的数据速率(kb/s)
# if=/dev/zero of=/dev/null bs=2G
# 系统可用内存空间不足2G,当一次性读2G大小数据时会发生内存交换,内存会交换一部分数据# 到磁盘上的交换空间中,因此,so ↑

io:
bi: 从块设备读入数据到系统的速率
bo: 保存数据至块设备的速率
# dd if=/dev/sda of=/dev/null
# 读磁盘数据,首先会加载到内存中,bi ↑

system:
in: interrupts 中断速率,包括时钟
cs: context switch 进程切换速率

cpu:
us: Time spent running non-kernel code
sy: Time spent running kernel code
id: Time spent idle. Linux 2.5.41前,包括IO-wait time.
wa: Time spent waiting for IO. 2.5.41前,包括in idle.
st: Time stolen from a virtual machine. 2.6.11前, unknown.

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@Rocky8-mini ~]# vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1389468 4252 225424 0 0 43 10 47 90 0 0 100 0 0
[root@Rocky8-mini ~]# vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 0 1389656 4252 225468 0 0 43 10 47 90 0 0 100 0 0
0 0 0 1389468 4252 225468 0 0 0 0 106 150 0 0 99 0 0
0 0 0 1389468 4252 225468 0 0 0 0 89 135 0 0 100 0 0
[root@Rocky8-mini ~]# vmstat -s
1833232 K total memory
213812 K used memory
81988 K active memory
164084 K inactive memory
1389708 K free memory
4252 K buffer memory
225460 K swap cache
2097148 K total swap
0 K used swap
2097148 K free swap
177 non-nice user cpu ticks
0 nice user cpu ticks
1140 system cpu ticks
444917 idle cpu ticks
22 IO-wait cpu ticks
357 IRQ cpu ticks
301 softirq cpu ticks
0 stolen cpu ticks
190362 pages paged in
42375 pages paged out
0 pages swapped in
0 pages swapped out
211123 interrupts
402441 CPU context switches
1671328052 boot time
1763 forks

2.12 统计CPU和设备IO信息 iostat

iostat 提供更丰富的IO性能状态数据,由sysstat包提供

常用选项

1
2
3
4
5
-c  只显示CPU行
-d 显示设备使用状态
-k 以千字节为单位显示输出
-t 在输出中包括时间戳
-x 在输出中包括扩展的磁盘指标

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[root@Rocky8-mini ~]# iostat
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/17/2022 _x86_64_ (2 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0.04 0.00 0.39 0.00 0.00 99.57

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
scd0 0.02 0.43 0.00 1041 0
sdc 0.05 1.23 0.00 2992 0
sdb 0.07 2.36 0.00 5727 2
sda 2.67 74.41 17.47 180663 42422
dm-0 2.44 50.91 16.61 123619 40325
dm-1 0.04 0.91 0.00 2220 0
dm-2 0.05 0.89 0.00 2169 12

[root@Rocky8-mini ~]# iostat 1 2
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/17/2022 _x86_64_ (2 CPU)

avg-cpu: %user %nice %system %iowait %steal %idle
0.04 0.00 0.39 0.00 0.00 99.57

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
scd0 0.02 0.42 0.00 1041 0
sdc 0.04 1.21 0.00 2992 0
sdb 0.07 2.32 0.00 5727 2
sda 2.63 73.04 17.18 180671 42488
dm-0 2.40 49.98 16.33 123627 40392
dm-1 0.04 0.90 0.00 2220 0
dm-2 0.04 0.88 0.00 2169 12

avg-cpu: %user %nice %system %iowait %steal %idle
0.00 0.00 0.00 0.00 0.00 100.00

Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
scd0 0.00 0.00 0.00 0 0
sdc 0.00 0.00 0.00 0 0
sdb 0.00 0.00 0.00 0 0
sda 0.00 0.00 0.00 0 0
dm-0 0.00 0.00 0.00 0 0
dm-1 0.00 0.00 0.00 0 0
dm-2 0.00 0.00 0.00 0 0

# dm: device mapper, 如果分区时使用了LVM,则一般生成dm-N逻辑卷
# tps: 设备每秒的传输次数。"一次传输"指的是"一次I/O请求"。多个逻辑请求可能会被合并为"一次I/O请求"。"一次传输"请求的大小是未知的。
kB_read/s:每秒从设备读取的数据量
kB_wrtn/s:每秒从设备写入的数据量
kB_read:读取的数据总量
kB_wrtn:写入的总数据量;单位 Kilobytes

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@Rocky8-mini ~]# iostat -d sdb -t -k 1 2
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/17/2022 _x86_64_ (2 CPU)

12/17/2022 09:39:47 PM
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sdb 0.06 1.83 0.00 5727 2

12/17/2022 09:39:48 PM
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sdb 0.00 0.00 0.00 0 0


[root@Rocky8-mini ~]# iostat -d sdb -x
Linux 4.18.0-348.el8.0.2.x86_64 (Rocky8-mini) 12/17/2022 _x86_64_ (2 CPU)

Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
sdb 0.06 0.00 1.77 0.00 0.00 0.00 0.00 0.00 0.14 1.00 0.00 31.82 2.00 0.34 0.00

r/s: 每秒合并后读的请求数
w/s: 每秒合并后写的请求数
rsec/s:每秒读取的扇区数;
wsec/:每秒写入的扇区数。
rKB/s:The number of read requests that were issued to the device per second
wKB/s:The number of write requests that were issued to the device per second
rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge)
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了
%rrqm: The percentage of read requests merged together before being sent to the device.
%wrqm: The percentage of write requests merged together before being sent to the device.
avgrq-sz 平均请求扇区的大小
avgqu-sz 是平均请求队列的长度。毫无疑问,队列长度越短越好
await: 每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。这个时间包括了队列时间和服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题
svctm 表示平均每次设备I/O操作的服务时间(以毫秒为单位)。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)

2.13 监视磁盘 I/O iotop

提供类似于top命令一般的UI界面,可查看每个进程是如何使用IO。来自于iotop包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@Rocky8-mini ~]# iotop

Total DISK READ : 51.17 K/s | Total DISK WRITE : 562.88 K/s
Actual DISK READ: 1090.34 K/s | Actual DISK WRITE: 2.24 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
1685 be/7 root 51.17 K/s 562.88 K/s 0.00 % 0.09 % mandb -q
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --switched-root --system --deserialize 18
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
3 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_gp]
4 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_par_gp]
6 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/0:0H-events_highpri]
9 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [mm_percpu_wq]
10 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0]
11 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_sched]
12 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [migration/0]
13 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [watchdog/0]
14 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [cpuhp/0]

iotop 常用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
OPTIONS
--version
Show the version number and exit

-h, --help
Show usage information and exit

-o, --only
Only show processes or threads actually doing I/O, instead of showing all processes or threads. This can be dynamically toggled by pressing o.

-b, --batch
Turn on non-interactive mode. Useful for logging I/O usage over time.

-n NUM, --iter=NUM
Set the number of iterations before quitting (never quit by default). This is most useful in non-interactive mode.

-d SEC, --delay=SEC
Set the delay between iterations in seconds (1 second by default). Accepts non-integer values such as 1.1 seconds.

-p PID, --pid=PID
A list of processes/threads to monitor (all by default).

-u USER, --user=USER
A list of users to monitor (all by default)

-P, --processes
Only show processes. Normally iotop shows all threads.

-a, --accumulated
Show accumulated I/O instead of bandwidth. In this mode, iotop shows the amount of I/O processes have done since iotop started.

-k, --kilobytes
Use kilobytes instead of a human friendly unit. This mode is useful when scripting the batch mode of iotop. Instead of choosing the most appropriate unit iotop will display all sizes in kilobytes.

-t, --time
Add a timestamp on each line (implies --batch). Each line will be prefixed by the current time.

-q, --quiet
suppress some lines of header (implies --batch). This option can be specified up to three times to remove header lines.
-q column names are only printed on the first iteration,
-qq column names are never printed,
-qqq the I/O summary is never printed.


交互按键

1
2
3
4
5
6
7
left 和 right 方向键: 改变排序
r: 反向排序
o: 切换至选项--only
p: 切换至--processes选项
a: 切换至--accumulate选项
q: 退出
i: 改变线程的优先级

2.14 显示网络带宽使用情况 iftop

来自于epel源的iftop包

1
2
3
4
[root@Rocky8-mini ~]# iftop
interface: eth0
IP address is: 192.168.119.128
MAC address is: 00:0c:29:4d:a8:89

image-20221218110425313

2.15 查看网络实时吞吐量 nload

nload 是一个实时监控网络流量和带宽的使用情况,以数值和动态图展示进出的流量情况,通过epel源安装

image-20221218110810806

界面操作

1
2
3
上下方向键、左右方向键、enter键或者tab键都就可以切换查看多个网卡的流量情况
按 F2 显示选项窗口
按 q 或者 Ctrl+C 退出 nload

示例

1
2
3
4
5
6
7
8
9
10
#默认只查看第一个网络的流量进出情况
nload
#在nload后面指定网卡,可以指定多个,按左右键分别显示网卡状态
nload eth0 eth1
#设置刷新间隔:默认刷新间隔是100毫秒,可通过 -t 命令设置刷新时间(单位是毫秒)
nload -t 500 eth0
#设置单位:显示两种单位一种是显示Bit/s、一种是显示Byte/s,默认是以Bit/s,也可不显示/s
#-u h|b|k|m|g|H|B|K|M|G 表示的含义: h: auto, b: Bit/s, k: kBit/s, m: MBit/s, H:
auto, B: Byte/s, K: kByte/s, M: MByte/s
nload -u M eth0

2.16 网络监视工具 iptraf-ng

来自于iptraf-ng包,可以对网络进行监控,对终端窗口大小有要求.

image-20221218112027899

image-20221218112106679

2.17 系统资源统计 dstat

dstat 由pcp-system-tools包提供,但安装dstat包即可, 可用于代替 vmstat,iostat功能

格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
dstat [-afv] [options..] [delay [count]]

-c 显示cpu相关信息
-C #,#,...,total
-d 显示disk相关信息
-D total,sda,sdb,...
-g 显示page相关统计数据
-m 显示memory相关统计数据
-n 显示network相关统计数据
-p 显示process相关统计数据
-r 显示io请求相关的统计数据
-s 显示swapped相关的统计数据
--tcp
--udp
--unix
--raw
--socket
--ipc
--top-cpu:显示最占用CPU的进程
--top-io: 显示最占用io的进程
--top-mem: 显示最占用内存的进程
--top-latency: 显示延迟最大的进程

示例

1
2
3
4
5
6
7
8
9
10
11
[root@Rocky8-mini ~]# dstat 
You did not select any stats, using -cdngy by default.
----total-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read writ| recv send| in out | int csw
0 0 100 0 0| 0 0 | 217B 890B| 0 0 | 115 191
0 0 99 0 0| 0 0 | 218B 558B| 0 0 | 109 188
0 0 100 0 0| 0 0 | 219B 568B| 0 0 | 107 164
0 0 99 0 0| 0 0 | 218B 565B| 0 0 | 103 179
0 1 100 0 0| 0 9406k| 218B 656B| 0 0 | 137 192
0 0 99 0 0| 0 0 | 218B 583B| 0 0 | 127 195
0 0 100 0 0| 0 0 | 217B 565B| 0 0 | 103 174 ^C

2.18 综合监控工具 glances

此工具可以通过EPEL源安装,可以监控其它主机的系统状态,不同版本之间不兼容

格式

1
2
glances [-bdehmnrsvyz1] [-B bind] [-c server] [-C conffile] [-p port] [-P
password] [--password] [-t refresh] [-f file] [-o output]

内建命令

1
2
3
4
5
6
7
8
9
10
a Sort processes automatically              l Show/hide logs
c Sort processes by CPU% b Bytes or bits for network I/O
m Sort processes by MEM% w Delete warning logs
p Sort processes by name x Delete warning and critical logs
i Sort processes by I/O rate 1 Global CPU or per-CPU stats
d Show/hide disk I/O stats h Show/hide this help screen
f Show/hide file system stats t View network I/O as combination
n Show/hide network stats u View cumulative network I/O
s Show/hide sensors stats q Quit (Esc and Ctrl-C also work)
y Show/hide hddtemp stats

常用选项

1
2
3
4
5
6
7
8
-b:  以Byte为单位显示网卡数据速率
-d: 关闭磁盘I/O模块
-f /path/to/somefile: 设定输入文件位置
-o {HTML|CSV}: 输出格式
-m: 禁用mount模块
-n: 禁用网络模块
-t #: 延迟时间间隔
-1: 每个CPU的相关数据单独显示

C/S 模式下运行glances命令

  • 服务器模式

    glances -s -B IPADDR

    ​ IPADDR:指明监听的本机哪个地址,默认端口为61209/tcp

  • 客户端模式

    glances -c IPADDR

    ​ IPADDR:要连入的服务器端地址

示例

1
2
3
4
5
6
# 服务器打开监听地址和端口
[root@Rocky8-mini ~]# glances -s
Glances XML-RPC server is running on 0.0.0.0:61209

# 客户端连接,查看连接的服务器的系统运行状况
[root@Rocky8-mini2 ~]# glances -c 192.168.119.128

image-20221218144617071

2.19 查看进程打开文件 lsof

lsof:list open files,查看当前系统文件的工具。在linux环境下,一切皆文件,用户通过文件不仅可以访问常规数据,还可以访问网络连接和硬件如传输控制协议 (TCP) 和用户数据报协议 (UDP)套接字等,系统在后台都为该应用程序分配了一个文件描述符

常用选项

1
2
3
4
5
6
7
8
9
10
11
12
13
-a:列出打开文件存在的进程
-c<进程名>:列出指定进程所打开的文件
-g:列出GID号进程详情
-d<文件号>:列出占用该文件号的进程
+d<目录>:列出目录下被打开的文件
+D<目录>:递归列出目录下被打开的文件
-n<目录>:列出使用NFS的文件
-i<条件>:列出符合条件的进程(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件
-u:列出UID号进程详情
-h:显示帮助信息
-v:显示版本信息。
-n: 不反向解析网络名字

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# lsof 列出当前所有打开的文件
[root@Rocky8-mini ~]# lsof

# 查看当前哪个进程正在使用此文件
[root@Rocky8-mini ~]# lsof /var/log/messages
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1018 root 5w REG 253,0 397817 34154191 /var/log/messages

# 查看由登录用户启动而非系统启动的进程
lsof /dev/pts/0
[root@Rocky8-mini ~]# lsof `tty`

# 指定进程号,可以查看该进程打开的文件
lsof -p PID
[root@Rocky8-mini ~]# lsof -p `pidof bc`

# 查看指定程序打开的文件
[root@Rocky8-mini ~]# lsof -c bc

# 查看指定用户打开的文件
[root@Rocky8-mini ~]# lsof -u root

# 查看指定目录下被打开的文件,参数+D为递归列出目录下被打开的文件;参数+d为列出目录下被打开的文件
lsof +D /var/log/
lsof +d /var/log/

# 查看所有网络连接,通过参数-i查看网络连接的情况,包括连接的ip、端口等,以及一些服务的连接情况。也可以通过指定ip查看该ip的网络连接情况
lsof -i -n
lsof -i@127.0.0.1

# 查看端口连接情况,通过'-i:PORT'可以查看端口的占用情况,-i 参数还可以查看协议、ip的连接情况等
lsof -i:80 -n

# 查看指定进程打开的网络连接,参数-i 查看网络连接情况,-a 查看存在的进程,-p 指定进程号
lsof -i -n -a -p 1593

# #查看指定状态的网络连接,-n:no host names, -P:no port names,-i TCP指定协议,-s指定协议状态通过多个参数可以清晰的查看网络连接情况、协议连接情况等
lsof -n -P -i TCP -s TCP:ESTABLISHED

实例:利用 lsof 恢复正在使用中的误删除的文件

1
2
3
4
[root@Rocky8-mini ~]# rm -f file.txt
[root@Rocky8-mini ~]# lsof | grep file.txt
vim 16943 root 6u REG 253,0 12288 51002071 /root/.file.txt.swp
[root@Rocky8-mini ~]# cat /proc/16943/fd/6 > file.txt

2.22 信号发送 kill

kill:内部命令,向进程发送控制信号,实现对进程的管理,每个信号对应一个数字,信号名称以SIG开头,不区分大小写

显示当前系统可用信号

1
2
3
4
5
kill -l
trap -l

# 查看帮助
man 7 signal

常用信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1) SIGHUP    无须关闭进程而让其重读配置文件
2) SIGINT 中止正在运行的进程,相当于ctrl+c
3) SIGQUIT 相当于ctrl+\
4) SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失
15) SIGTERM 终止正在运行的进程,默认信号
18) SIGCONT 继续运行
19) SIGSTOP 后台休眠

# 指定信号的三种方式
- 信号的数字表示:1,2,9
- 信号的完整名称:SIGHUP/sighup
- 信号的简写名称:HUP/hup

注:许多服务支持的reload操作,实际就是发送了HUP信号

向进程发送信号:

  • 按照 PID
1
2
kill [-signal|-s signal|-p] [-q value] [-a] [--] pid|name...
kill -l [number] | -L

示例

1
2
3
4
5
kill -1 pid ...
kill -n 9 pid
kill -s SIGINT pid
[root@centos7 ~]# kill -term `pidof ping`
[root@centos7 ~]# kill -sigterm `pidof ping`
  • 按照名称,killall 来自于psmisc包
1
2
3
4
killall - kill processes by name
killall [-SIGNAL] command...

[root@Rocky8-mini ~]# killall -TERM ping
  • 按照模式
1
2
3
4
5
6
7
8
9
10
pkill [options] pattern

[options]
-SIGNAL
-u uid: effective user, 生效者
-U uid: real user, 真正发起运行命令的用户
-t terminal: 与指定终端相关的进程
-l: 显示进程名 (pgrep 可用)
-a: 显示完整格式的进程名 (pgrep 可用)
-P pid: 显示指定进程的子进程

示例:利用 0 信号实现进程的健康性检查

1
2
3
4
5
6
7
8
9
10
11
12
[root@Rocky8-mini ~]# man kill
If signal is 0, then no actual signal is sent, but error checking is still performed.

[root@Rocky8-mini ~]# killall -0 ping
[root@Rocky8-mini ~]# echo $?
0
[root@Rocky8-mini ~]# killall -0 ping
ping: no process found
[root@Rocky8-mini ~]# echo $?
1

# 此方式有局限性,即使进程处于停止或僵尸状态,也会认为进程是健康的

示例:pkill 和 pgrep支持正则表达式

1
2
3
4
5
[root@Rocky8-mini ~]# pgrep -a '^p'
950 /usr/lib/polkit-1/polkitd --no-debug
2229 ping www.baidu.com

[root@Rocky8-mini ~]# pkill '^p'

2.23 作业管理

Linux 的作业控制

  • 前台作业:通过终端启动,且启动后一直占据终端
  • 后台作业:可通过终端启动,但启动后转入后台运行

让作业运行于后台

  • 运行中的作业:Ctrl + z
  • 尚未启动的作业:COMMAND &

后台作业虽然被送往后台运行,但依然与终端相关;退出终端,将关闭后台作业。如果希望送往后台作业剥离与终端的关系,执行以下方法:

  • nohup COMMMAND &> /dev/null &
  • screen; COMMAND
  • tmux; COMMAND

查看当前终端所有作业:

1
jobs

作业控制

1
2
3
fg [[%]JOB_NUM]:  把指定的后台作业调回前台
bg [[%]JOB_NUM]: 让送往后台的作业在后台继续运行
kill [%JOB_NUM]: 终止指定的作业

示例:后台运行的进程和终端的关系

1
2
3
4
5
6
7
8
9
10
11
12
# 终端1中运行后台进程
[root@Rocky8-mini ~]# ping 127.0.0.1 &
[1] 2270

# 终端2中可以查看到进程
[root@Rocky8-mini ~]# ps aux | grep ping
root 2270 0.0 0.1 32460 2316 pts/1 S 22:16 0:00 ping 127.0.0.1
root 2272 0.0 0.0 12136 1032 pts/0 S+ 22:19 0:00 grep --color=auto ping

# 关闭终端1,终端2将查看不到进程
[root@Rocky8-mini ~]# ps aux | grep ping
root 2278 0.0 0.0 12136 1156 pts/0 S+ 22:20 0:00 grep --color=auto ping

示例:nohup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@Rocky8-mini ~]# rpm -qf `which nohup`
coreutils-8.30-12.el8.x86_64

[root@Rocky8-mini ~]# nohup ping 127.0.0.1
nohup: ignoring input and appending output to 'nohup.out'

[root@Rocky8-mini ~]# tail -f nohup.out
64 bytes from 127.0.0.1: icmp_seq=34 ttl=64 time=0.030 ms
64 bytes from 127.0.0.1: icmp_seq=35 ttl=64 time=0.040 ms
64 bytes from 127.0.0.1: icmp_seq=36 ttl=64 time=0.032 ms
64 bytes from 127.0.0.1: icmp_seq=37 ttl=64 time=0.029 ms

[root@Rocky8-mini ~]# nohup ping 127.0.0.1 &> /dev/null &
[1] 2345
[root@Rocky8-mini ~]# ps aux | grep nohup
root 2353 0.0 0.0 12136 1124 pts/0 S+ 22:35 0:00 grep --color=auto nohup
[root@Rocky8-mini ~]# pstree -p |grep ping
|-sshd(968)-+-sshd(1511)---sshd(1523)---bash(1524)---ping(2345)

# 关闭对应的终端,再观察进程的父进程
[root@Rocky8-mini ~]# pstree -p |grep ping
|-ping(2345)

2.24 并行运行

利用后台执行,实现并行功能,即同时运行多个进程,提高效率

方式一

1
2
3
4
cat all.sh
f1.sh&
f2.sh&
f3.sh&

方式二

1
(f1.sh&);(f2.sh&);(f3.sh&)

方式三

1
f1.sh&f2.sh&f3.sh&

示例:多组命令实现并行

1
{ ping -c3 127.1; ping 127.2; }& { ping -c3 127.3; ping 127.4; }&

示例

1
2
3
4
5
6
7
[root@Rocky8-mini ~]# cat test.sh 
#!/bin/bash
net=192.168.0
for i in {100..110};do
{ ping -c1 -w1 ${net}.${i} &> /dev/null && echo ${net}.${i} is up || echo ${net}.${i} is done; }&
done
wait

三、任务计划

通过任务计划,让系统自动的按时间或周期性执行任务,需要先实现邮件通知

1
2
[root@Rocky8-mini ~]# dnf -y install postfix
[root@Rocky8-mini ~]# systemctl enable --now postfix.service

未来的某一个时间点执行一次任务

  • at 指定时间点,执行一次任务
  • batch 系统自行选择空闲时间去执行指定的任务

周期性运行任务

  • cron

3.1 一次性任务

at 工具

  • 由包 at 提供
  • 依赖于 atd 服务,需要启动才能实现 at 任务
  • at 队列存放在 /var/spool/at 目录中,Ubuntu 存放在 /var/spool/cron/atjobs 目录下
  • 执行任务时PATH变量的值和当前定义任务的用户身份一致

at 命令

1
2
3
4
5
6
7
8
9
10
11
at [option] TIME

-V 显示版本信息
-t time 时间格式 [[CC]YY]MMDDhhmm[.ss]
-l 列出指定队列中等待运行的作业,相当于atq
-d N 删除指定的N号作业;相当于atrm
-c N 查看具体作业N号任务
-f file 指定的文件中读取任务
-m 当任务被完成之后,将给用户发送邮件,即使没有标准输出

注意:作业执行命令的结果中的标准输出和错误以执行任务的用户身份发邮件通知给root;默认8中的最小化安装没有安装邮件服务器,需要自行安装

TIME:定义什么时候进行 at 这项任务的时间

1
2
3
HH:MM [YYYY-mm-dd]
noon, midnight, teatime(4pm), tomorrow
now+#{mintes,hours,days, OR weeks}

示例:at 时间格式

1
2
3
4
5
6
7
8
9
10
11
HH:MM  在今日的 HH:MM 进行,若该时刻已过,则明天此时执行任务

HH:MM YYYY-MM-DD 规定在某年某月的某一天的特殊时刻进行该项任务

HH:MM[am|pm] [Month] [Date]
06pm March 17
17:20 tomorrow

HH:MM[am|pm] + number [minutes|hours|days|weeks],在某个时间点再加几个时间后才进行该项任务
now + 5 min
02pm + 3 day

at 任务执行方式

  • 交互式
  • 输入重定向
  • at -f file

/etc/at.{allow,deny} 控制用户能否执行 at 任务

  • 白名单:/etc/at.allow 默认不存在,只有该文件中的用户才能执行 at 命令
  • 黑名单:/etc/at.deny 默认存在,拒绝该文件中用户执行 at 命令,而没有在此文件中则可以使用
  • 如果两个文件都不存在,只有root可以执行 at 命令

示例:Ubuntu at 任务存放路径

1
2
3
4
5
6
7
8
9
10
11
12
root@ubuntu18-server:~# ll /var/spool/cron/
total 20
drwxr-xr-x 5 root root 4096 Sep 15 2021 ./
drwxr-xr-x 4 root root 4096 Sep 15 2021 ../
drwxrwx--T 2 daemon daemon 4096 Sep 15 2021 atjobs/
drwxrwx--T 2 daemon daemon 4096 Feb 20 2018 atspool/
drwx-wx--T 2 root crontab 4096 Nov 16 2017 crontabs/
root@ubuntu18-server:~# ll /var/spool/cron/atjobs/
total 12
drwxrwx--T 2 daemon daemon 4096 Sep 15 2021 ./
drwxr-xr-x 5 root root 4096 Sep 15 2021 ../
-rw------- 1 daemon daemon 2 Sep 15 2021 .SEQ

3.2 周期性计划任务 cron

周期性计划任务cron相关的程序包

  • cronie:主程序包,提供crond守护进程及相关辅助工具
  • crontabs:包含为Centos提供系统维护任务
  • cronie-anacron:cronie 的补充程序,用户监控cronie任务执行状况。如:cronie 中的任务在某一个时间点该运行的任务没有正常运行,则anacron会随后启动一次此任务

cron 依赖于crond服务,确保crond守护处于运行状态

1
systemctl status crond.service

cron 任务划分

  • 系统cron任务:系统维护作业,主配置文件/etc/crontab, 子配置文件/etc/cron.d
  • 用户cron任务:保存在/var/spool/cron/USERNAME(Ubuntu 系统存放在/var/spool/cron/crontabs/USERNAME),利用crontab命令管理

计划任务日志:/var/log/cron

3.2.1 系统cron计划任务

格式说明:/etc/crontab,crontab 命令使用:man 5 crontab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@Rocky8-mini ~]# cat /etc/crontab 
SHELL=/bin/bash # 默认的shell类型
PATH=/sbin:/bin:/usr/sbin:/usr/bin # 默认PATH变量,可修改
MAILTO=root # 默认标准输出和错误发邮件给root,可修改

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed

计划任务的简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 每隔5分钟执行一次命令
*/5 * * * * ls /tmp

# 每月的1号,4号,6号的2点整执行
0 2 1,4,6 * * ls /tmp

# 每月每日每小时的0分就执行
0 * * * * ls /tmp

# 每分钟执行一次命令
* * * * * ls /tmp

# 每周五的2点整执行(当不写日和月的时间时,仅周有效)
0 2 * * 5 ls /tmp

# 6月3日的5点10分执行或6月的每周日的5点10分执行
10 5 3 6 0 /usr/bin/touch /mnt/file1-`date +\%F_\%T`
# 每个月的3日的5点10分或者每周日的5点10分执行
10 5 3 * 0 /usr/bin/touch /data/file-`date +\%F_\%T`

帮助手册

1
2
3
4
5
6
7
8
9
10
11
12
[root@wh-ctyun ~]# man 5 crontab
The time and date fields are:

field allowed values
----- --------------
minute 0-59
hour 0-23
day of month 1-31
month 1-12 (or names, see below)
day of week 0-7 (0 or 7 is Sunday, or use names)

Note: The day of a command's execution can be specified in the following two fields — 'day of month', and 'day of week'. If both fields are restricted (i.e., do not contain the "*" character), the command will be run when either field matches the current time. For example, "30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.

3.2.2 用户计划任务

crontab 命令

  • 每个用户都有自己的cron任务文件:/var/spool/cron/USERNAME
  • 默认标准输出和错误输出会被发邮件给对应的用户
  • root 用户能够修改其它用户的作业
  • 用户的cron中默认的PATH=/usr/bin:/bin,如果使用其它路径,在任务文件中添加PATH

crontab 命令格式

1
2
3
4
5
6
7
8
crontab [-u user] [-l | -r | -e ] [-i]

常用选项:
-l 列出所有任务
-e 编辑任务
-r 移除所有任务
-i 同-r一同使用,以交互式模式移除指定任务
-u user 指定用户管理cron任务,仅root可运行

控制用户执行计划任务:/etc/cron.{allow,deny}

示例:关于计划任务中的PATH变量

1
2
3
4
5
6
# 方法1,直接指定PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

# 方法2,在书写命令时写全该命令的路径
[root@wh-ctyun ~]# crontab -l
10 5 3 6 * /usr/bin/touch /mnt/file-`date +\%F_\%T`

在cron任务中不建议使用%,其表示换行的特殊用途,且第一个%后的所有字符串会被当成命令的标准输入,如果在命令中需要使用到%,则需要使用到 \ 进行转义。