一:进程介绍
1.什么是进程?
- 正在执行的程序
- 正在计算机上执行的程序实例
- 能分配处理器并由处理器执行的实体
2.进程 与 程序
名称 | 描述 | 状态 |
---|---|---|
程序 | 存放代码的文件 | 静态 |
进程 | 程序的运行过程 | 动态 |
同一个程序可能对应多个进程
父进程与子进程:
- 父进程:程序运行时产生的第1个进程
- 子进程:由父进程衍生
fork()
出来的进程
注意:
如果父进程终止,子进程 也会随之被终止
3.进程状态
进程的两个基本元素是程序代码和代码相关联的数据集
进程是一种动态描述,但并不代表所有的进程都在运行,这就可以引入‘进程状态’
进程在内存中因策会略或调度需求, 会处于各种状态:
状态 | 描述 | STAT状态+符号 | 描述 |
---|---|---|---|
R | 进程运行 | s | 进程是控制进程, Ss进程的领导者,父进程 |
S | 可中断睡眠 | < | 进程运行在高优先级上,S<优先级较高的进程 |
T | 进程被暂停 | N | 进程运行在低优先级上,SN优先级较低的进程 |
D | 不可中断睡眠 | + | 当前进程运行在前台,R+该表示进程在前台运行(正在io操作,一旦停止,数据丢失) |
Z | 僵尸进程 | l | 进程是多线程的,Sl表示进程是以线程方式运行 |
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
R - 可执行状态(运行状态)
只有在运行状态的进程才有可能在CPU上运行,注意是可能,并不意味着进程一定在运行中
同一时刻可能有多个进程处在可执行状态,这些进程的PCB(进程控制块)被放入对应CPU的可执行队列中
然后进程调度器 从各个可执行队列中分别选择一个进程在CPU上运行
另外如果计算机只有一个处理器,那么一次最多只有一个进程处于这种状态
S - 可中断睡眠状态(sleeping)
处在这个状态意味着进程在等待事件完成
这些进程的PCB(task_struct结构)被放入对应时间的等待队列 中
然后等待的事件发生时,对应的进程将被唤醒
D - 不可中断睡眠(disk sleep)
在这个状态的进程通常会等待IO的结束
这个状态与sleeping状态相似,处于睡眠状态
但是此刻进程是不可中断的,意思是不响应异步信号。
另外你会发现处在D状态的进程kill -9
竟然也杀不死
这就相当于我们怎么也叫不醒一个装睡的人
T - 暂停状态
给进程发送一个SIGSTOP信号,进程就会响应信号进入T状态,除非该进程正处在D状态
再通过发送SIGCONT信号让进程继续运行
kill -SIGSTOP
kill -SIGCONT
Z - 僵死状态
僵死状态是一个比较特殊的状态
进程在退出的过程中,处于TASK_DEAD状态
在这个退出过程中,进程占有的所有资源将被回收,除了task_struct结构(以及少数资源)以外
于是进程就只剩下task_struct这么个空壳,故称为僵尸
X-死亡状态 或 退出状态(dead) 死亡状态是内核运⾏ kernel/exit.c ⾥的 do_exit() 函数返回的状态
这个状态只是⼀个返回状态, 你不会在任务列表⾥看到这个状态
4.进程状态切换
进程的3种状态
① 就绪态
当进程已分配到除CPU以外的所有必要的资源,只要获得处理机便可立即执行,这时的进程状态称为就绪状态
② 运行态
当进程已获得处理机,其程序正在处理机上执行,此时的进程状态称为执行状态
③ 阻塞态
正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态
引起进程阻塞的事件 可有多种,例如,等待I/O完成、申请缓冲区不能满足、等待信件(信号)等
状态切换
就绪 → 运行
处于就绪状态的进程,当进程调度程序为之分配了处理器后,该进程便由就绪状态转变成运行状态
运行 → 就绪
处于执行状态的进程在其执行过程中,因分配给它的一个时间片已用完而不得不让出处理机,于是进程从运行状态转变成就绪状态
运行 → 阻塞
正在执行的进程因等待某种事件(文件读写等IO操作)发生而无法继续执行时,便从运行状态变成阻塞状态
阻塞 → 就绪
处于阻塞状态的进程,若其等待的事件已经发生,于是进程由阻塞状态转变为就绪状态
5.进程的优先级
① 什么是优先级?
优先级(priority)是一种约定,优先级高的先做,优先级低的后做
优先级高的可以优先享受资源,比如排队买票时,军人优先、老人优先、人民币玩家优先等
② 为什么要有系统优先级?
举个栗子
海底捞火锅正常情况下响应服务就特别快
但是 当节假日来临时,顾客数量急剧上升,就会导致处理请求特别慢
假设我是海底捞SVIP客户(最高优先级),无论门店多么繁忙,我都不用排队
海底捞人员会直接服务于我,满足我的需求
哪些不是VIP的顾客(较低优先级)则进入排队等待状态
总结
③ 如何配置进程的优先级?
在启动进程时,为不同的进程使用不同的调度策略
- nice 值越高: 表示优先级越低,例如+19,该进程容易将CPU 使用量让给其他进程
- nice 值越低: 表示优先级越高,例如-20,该进程更不倾向于让出CPU
1.用top
或ps
命令查看进程的优先级
NI: 实际nice级别,默认是0。
PR: 显示nice值,-20映射到0,+19映射到39
[root@localhost ~]# top
top - 16:35:16 up 19 min, 1 user, load average: 0.00, 0.01, 0.01
Tasks: 103 total, 1 running, 101 sleeping, 1 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 995696 total, 736876 free, 156644 used, 102176 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 712688 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 127992 6604 4148 S 0.0 0.7 0:01.17 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
....
[root@localhost ~]# ps axo command,nice| grep vim
grep --color=auto vim 0
2.nice
指定程序的优先级
语法格式:
nice -n 优先级数字 进程名称
#1.开启vim并且指定程序优先级为-5
[root@localhost ~]# nice -n -5 vim &
[1] 1123
#2.查看该进程的优先级情况
[root@localhost ~]# ps axo command,nice| grep 1123
grep --color=auto 1123 0
[3]+ Stopped nice -n -5 vim
3.renice
命令修改一个正在运行的进程优先级
语法格式
renice -n 优先级数字 进程pid
# 1.查看sshd进程当前的优先级状态
[root@localhost ~]# ps axo pid,command,nice |grep [s]shd
70840 sshd: root@pts/2 0
98002 /usr/sbin/sshd -D 0
# 2.调整sshd主进程的优先级
[root@localhost ~]# renice -n -20 98002
98002 (process ID) old priority 0, new priority -20
# 3.调整之后记得退出终端
[root@localhost ~]# ps axo pid,command,nice |grep [s]shd
70840 sshd: root@pts/2 0
98002 /usr/sbin/sshd -D -20
[root@localhost ~]# exit
# 4.当再次登陆sshd服务,会由主进程fork子进程(那么子进程会继承主进程的优先级)
[root@localhost ~]# ps axo pid,command,nice |grep [s]shd
98002 /usr/sbin/sshd -D -20
98122 sshd: root@pts/0 -20
二:查看进程
1.常用组合ps aux
ps aux是常用组合,查看进程用户、PID、占用CPU百分比、占用内存百分比、状态、执行的命令
等
选项 | 释义 |
---|---|
-a | 显示一个终端的所有进程 |
-u | 选择有效的用户id或者是用户名 |
-x | 显示没有控制终端的进程,同时显示各个命令的具体路径。 |
实例
[root@localhost ~]# ps aux |head -5
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.6 128124 6740 ? Ss 07:32 0:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 07:32 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 07:32 0:00 [kworker/0:0H]
root 5 0.0 0.0 0 0 ? S 07:32 0:00 [kworker/u256:0]
实例状态分析
状态 | 释义 |
---|---|
USER | 启动进程的用户 |
PID | 进程运行的ID号 |
%CPU | 进程占用CPU百分比 |
%MEM | 进程占用内存百分比 |
VSZ | 进程占用虚拟内存大小 (单位KB:killobytes) |
RSS | 进程占用物理内存实际大小 (单位KB) |
TTY | 进程是由哪个终端运行启动的tty1、pts/0等 ?表示内核程序与终端无关(远程连接会通过tty打开一个bash:tty) |
STAT | 进程运行过程中的状态 man ps (/STATE) |
START | 进程的启动时间 |
TIME | 进程占用 CPU 的总时间(为0表示还没超过秒) |
COMMAND | 程序的运行指令,[ ] 属于内核态的进程 没有 [ ] 的是用户态进程。systemctl status 指令 |
STAT - 进程状态参数详解
状态 | 释义 |
---|---|
R | 运行 |
S | 可中断睡眠 Sleep 即在睡眠的过程中可以接收信号唤醒 -> 执行的IO操作可以得到硬件设备的响应 |
D | 不可中断睡眠 即在睡眠的过程中不可以接收信号唤醒 -> 执行的IO操作得不到硬件设备的响应 |
T | 停止的进程 |
Z | 僵尸进程 |
X | 死掉的进程(几乎看不见,因为死了就立即回收了) |
< | 标注了< 小于号代表优先级较高的进程 |
N | 代表优先级较低的进程 |
s | 包含子进程 |
+ | 表示是前台的进程组 |
l | 小写字母l,代表以线程的方式运行,即多线程 |
丨 | 管道符号代表多进程 |
2.Linux进程的2种睡眠状态
① Interruptible Sleep(可中断睡眠,在ps命令中显示“S”)
处在这种睡眠状态的进程是可以通过给它发送signal来唤醒的
比如:发HUP信号给nginx的master进程可以让nginx重新加载配置文件而不需要重新启动nginx进程
② Uninterruptible Sleep(不可中断睡眠,在ps命令中显示“D”)
处在这种状态的进程不接受外来的任何signal
这也是为什么之前我无法用kill杀掉这些处于D状态的进程
无论是kill
、kill-9
、kill-15
是按 Ctrl+C 、Ctrl+Z 都无济于,因为它们根本就不受这些信号的支配
解释
进程为什么会被置于D状态呢?
处于uninterruptible sleep状态的进程通常是在等待IO,比如磁盘IO,网络IO,其他外设IO
如果进程正在等待的IO在较长的时间内都没有响应,那么就很会不幸地被ps看到了
同时也就意味着很有可能有IO出了问题
可能是外设本身出了故障,也可能是比如NFS挂载的远程文件系统已经不可访问了
正是因为得不到IO的响应,进程才进入了uninterruptible sleep状态
所以要想使进程从uninterruptible sleep状态恢复,就得使进程等待的IO恢复
比如如果是因为从远程挂载的NFS卷不可访问导致进程进入uninterruptible sleep状态的
那么可以通过恢复该NFS卷的连接来使进程的IO请求得到满足
除此之外,要想干掉处在D状态进程就只能重启整个Linux系统了(恐怖的D状态)
看到有人说如果要想杀掉D状态的进程,通常可以去杀掉它的父进程(通常是shell,我理解的这种情况是在shell下直接运行的该进程,之后该进 程转入了D状态),于是我就照做了,之后就出现了上面的状态:
他们的父进程被杀掉了,但是他们的父进程PID都变成了1,也就是init进程,这下可如何是好?
此时我这些D状态的进程已经影响到其他一些进程的运行,而已经无法访问的NFS卷又在段时间内无法恢复,那么,只好重新启动了。
强调
D与Z状态的进程都无法用kill -9
杀死
3.实例
① 查看运行状态
# 1.(窗口1)执行vim
[darker@localhost ~]$ vim 1.txt
# 2.(窗口2)查看vim的运行状态为:S+
[root@localhost ~]# ps aux |grep [v]im
darker 11060 0.6 0.4 149280 4968 pts/1 S+ 09:27 0:00 vim 1.txt
# 3.(窗口1):Ctrl+z 将进程防止到后台
[1]+ Stopped vim 1.txt
# 4.(窗口2):查看vim的运行状态为:T
[root@localhost ~]# ps aux |grep [v]im
darker 11060 0.0 0.5 149280 5008 pts/1 T 09:27 0:00 vim 1.txt
② 查看S+、R+、D+
# 1.(窗口1)执行vim
[darker@localhost ~]$ tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
# 2.(窗口2)查看vim的运行状态为:S+
[root@localhost ~]# while true;do ps aux |grep [t]ar;sleep 0.3;clear;done
darker 11100 14.5 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.6 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.4 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.4 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.5 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.3 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.4 0.4 126972 4456 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.5 0.4 126972 4688 pts/1 S+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
darker 11100 14.3 0.4 126972 4688 pts/1 R+ 09:32 0:09 tar cvzf darker.tar.gz /etc/ /usr/ /var/ /usr/
...
③ 查看进程树
# 安装pstree
④ 查看ppid
[root@localhost ~]# ps -ef | head -10
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:32 ? 00:00:01 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
root 2 0 0 07:32 ? 00:00:00 [kthreadd]
root 4 2 0 07:32 ? 00:00:00 [kworker/0:0H]
root 5 2 0 07:32 ? 00:00:00 [kworker/u256:0]
root 6 2 0 07:32 ? 00:00:00 [ksoftirqd/0]
root 7 2 0 07:32 ? 00:00:00 [migration/0]
root 8 2 0 07:32 ? 00:00:00 [rcu_bh]
root 9 2 0 07:32 ? 00:00:02 [rcu_sched]
root 10 2 0 07:32 ? 00:00:00 [lru-add-drain]
4.动态查看
基本用法
[root@localhost ~]# top
[root@localhost ~]# top -d 1 # 1秒刷新一次
[root@localhost ~]# top -d 1 -p 进程的pid
[root@localhost ~]# top -d 1 -p `pgrep nginx | head -1`
[root@localhost ~]# top -d 1 -p `pgrep sshd | head -1`,33 # 查看sshd以及pid为33的
[root@localhost ~]# top -d 1 -u nginx # 查看指定用户进程
[root@localhost ~]# top -b -n 2 > top.txt # 将2次top信息写入到文件
top的参数详解
参数 | 描述 |
---|---|
up左边的时间 | 当前系统时间 |
up右边的时间 | 运行了多长时间 |
users | 当前登录的用户数 |
load average | CPU 1分钟的平均负载 CPU 2分钟的平均负载 CPU 15分钟的平均负载 |
Tasks | total:总任务数 running:正在运行的进程数 sleeping:休眠的进程数 stopped:停止的进程数 zombie:僵尸进程数 |
%Cpu(s) | us:用户态进程占用cpu时间的百分比 sys:内核态进程占用cpu时间的百分比 ni:代表优先被调度的进程占cpu时间的百分比 id:cpu空闲的百分比 wa:cpu等待io的百分比 hi:硬件中断,处理硬件中断所占用CPU的时间 si:软件中断,处理软件中断所占用CPU的时间 st:被偷走的cpu百分比 |
KiB Men | total:总物理内存 free:空闲物理内存 used:已用物理内存 buff/cache:缓存 |
KiB Swap | total:总交换分区内存 free:空闲交换分区内存 used:已用交换分区内存 avail Men:可用内存 |
PID | 进程的ID |
USER | 进程属于哪个用户 |
PR | 进程的优先级 |
NI | 进程的优先值(nice值) |
VIRT | 进程使用的虚拟内存大小 |
RES | 进程的常驻内存 |
SHR | 进程的共享内存 |
S | 进程的状态: D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 |
%CPU | 进程占用CPU的百分比(可用超出100%,取决于有几个CPU) |
%MEM | 进程占用五路内存的百分比 |
TIME+ | 进程使用CPU的时间(单位:1/100秒) |
COMMAND | 进程名称(该进程由哪条命令执行的) |
进程信息
- VIRT:virtual memory usage 虚拟内存
① 进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
② 假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量
- RES:resident memory usage 常驻内存
① 进程当前使用的内存大小,但不包括swap out(当某进程向OS请求内存发现不足时,OS会把内存中暂时不 用的数据交换出去,放在SWAP分区中,这个过程称为SWAP OUT。当某进程又需要这些数据且OS发现还有空闲 物理内存时,又会把SWAP分区中的数据交换回物理内存中,这个过程称为SWAP IN)
② 包含其他进程的共享
③ 如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
④ 关于库占用内存的情况,它只统计加载的库文件所占内存大小
- SHR:shared memory 共享内存
① 除了自身进程的共享内存,也包括其他进程的共享内存
② 虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
③ 计算某个进程所占的物理内存大小公式:RES – SHR
④ swap out后,它将会降下来,因为内存充裕了,大家就没必要合租内存了
- DATA
① 数据占用的内存。如果top没有显示,按f键、然后用空格选中DATA项目、然后按q则可以显示出来。
② 真正的该程序要求的数据空间,是真正在运行中要使用的
top 的内部命令对进程的显示方式进行控制
命令 | 作用 |
---|---|
M | 按内存的使用排序 |
P | 按CPU使用排序 |
N | 以PID的大小排序 |
R | 对排序进行反转 |
f | 自定义显示字段 |
1 | 显示所有CPU的负载 |
s | 改变画面更新频率 |
h / ? | 帮助 |
< | 向前 |
> | 向后 |
z | 彩色 |
l | 关闭或开启第一部分第一行 top 信息的表示 |
t | 关闭或开启第一部分第二行 Tasks 和第三行 Cpus 信息的表示 |
m | 关闭或开启第一部分第四行 Mem 和 第五行 Swap 信息的表示 |
n | 设置在进程列表所显示进程的数量 |
q | 退出top |
序号与列名
序号 | 列名 | 含义 |
---|---|---|
a | PID | 进程id |
b | PPID | 父进程id |
c | RUSER | Real user name 真实的用户名 |
d | UID | 进程所有者的用户id |
e | USER | 进程所有者的用户名 |
f | GROUP | 进程所有者的组名 |
g | TTY | 启动进程的终端名。不是从终端启动的进程则显示为 ? |
h | PR | 优先级 |
i | NI | nice值:负值表示高优先级,正值表示低优先级 |
j | P | 最后使用的CPU,仅在多CPU环境下有意义 |
k | %CPU | 上次更新到现在的CPU时间占用百分比 |
l | TIME | 进程使用的CPU时间总计,单位秒 |
m | TIME+ | 进程使用的CPU时间总计,单位1/100秒 |
n | %MEM | 进程使用的物理内存百分比 |
o | VIRT | 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
p | SWAP | 进程使用的虚拟内存中,被唤出的大小,单位kb |
q | RES | 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
r | CODE | 可执行代码占用的物理内存大小,单位kb |
s | DATA | 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb |
t | SHR | 共享内存大小,单位kb |
u | nFLT | 页面错误次数 |
v | nDRT | 最后一次写入到现在,被修改过的页面数。 |
w | S | 进程状态 (D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程) |
x | COMMAND | 命令名/命令行 |
y | WCHAN | 若该进程在睡眠,则显示睡眠中的系统函数名 |
z | Flags | 任务标志,参考 sched.h |
三:shell管理进程
1.优先级管理
可以在启动进程时用nice命令设置设置优先级
① 命令
nice [-n <优先级>] [--help] [--version] [执行指令]
② 选项
若 nice命令未指定优先级的调整值,则以缺省值10来调整程序运行优先级,既在当前程序运行优先级基础之 上增加10
选项 | 释义 |
---|---|
-n <优先级> | 指定优先级 |
--help | 帮助信息; |
--version | 版本信息; |
③ 执行范例:让命令以新的优先级执行
[root@localhost ~]# $ nice -n 5 ls # nice -n -20 命令
④ ps -l 命令
其中的几个重要信息
参数 | 描述 |
---|---|
UID | 代表执行者的身份 |
PID | 代表这个进程的代号 |
PPID | 代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号 |
PRI | 代表这个进程可被执行的优先级,其值越小越早被执行 |
NI | 代表这个进程的nice值 |
PRI即进程的优先级,此值越小进程的优先级别越高
而NI,也就是我们所要说的nice值(通过nice命令设 置),其表示进程可被执行的优先级的修正数值
如前面所说,PRI值越小越快被执行,那么加入nice值后, 将会使得PRI变为:PRI(new)=PRI(old)+nice
所以,nice命令设置的优先级不是程序最终的优先级,而只是优先级的修正数值
renice命令允许用户修改一个正在运行的进程的优先权
也可以对已运行的进程设置新的优先级
[root@localhost ~]# renice -20 11111
2.给进程发送信号
列出所有支持的信号
[root@localhost ~]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
部分信号解析
# HUP(1)
1. 挂起信号
2. 往往可以让进程重新加载配置
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时
通知同一session内的各个作业, 这时它们与控制终端不再关联
登录Linux时,系统会分配给登录用户一个终端(Session)
在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都 属于这个 Session
当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号
这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止
不过,可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件
# INT(2): 中断,
通常因为按下ctrl+c而产生的信号,用于通知前台进程组终止进程
# QUIT(3): 退出
和SIGINT类似, 但由QUIT字符(通常是Ctrl-)来控制
进程在因收到SIGQUIT退出时会产生core文件, 在这个意义上类似于一个程序错误信号
# TSTP(20): 停止进行运行
通常因为按下ctrl+z而产生的信号
# KILL (9)
用来立即结束程序的运行. 本信号不能被阻塞、处理和忽略
如果管理员发现某个进程终止不了,可尝试发送这个信号
# TERM(15):
终止,是不带参数时kill默认发送的信号,默认是杀死进程,与SIGKILL不同的是该信号可以被阻塞和处理
通常用TERM信号来要求程序自己正常退出,如果进程终止不了,我们才会尝试SIGKILL
# CONT(18) 被暂停的进程将继续恢复运行
# SIGSTOP(19) 暂停进程
# SIGCHLD
子进程结束时, 父进程会收到这个信号。
如果父进程没有处理这个信号,也没有等待(wait)子进程
子进程虽然终止,但是还会在内核进程表中占有表项,这时的子进程称为僵尸进程。
这种情况我们应该避免(父进程或者忽略SIGCHILD信号,或者捕捉它,或者wait它派生的子进程,或者父进程先终止,这时子进程的终止自动由init进程来接管)
kill - 根据PID杀死进程
- kill -9:强制杀死进程
- kill -15:正常退出进程
- kill -19:暂停进程
- kill -18:恢复进程
# 安装vsftpd
[root@localhost ~]# yum install vsftpd -y
# 启动vsftpd
[root@localhost ~]# systemctl start vsftpd
# 查看vsftp进程信息
[root@localhost ~]# ps aux|grep vsftpd
root 20249 0.0 0.0 53288 576 ? Ss 11:22 0:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
root 20251 0.0 0.0 112812 968 pts/0 S+ 11:23 0:00 grep --color=auto vsftpd
# 发送重载信号,例如:vsftpd 的配置文件发生改变,希望重新加载
[root@localhost ~]# kill -1 20249
# 发送停止信号,当然vsftpd 服务有停止的脚本 systemctl stop vsftpd
[root@localhost ~]# kill 20249
# 发送强制停止信号,当无法停止服务时,可强制终止信号
[root@localhost ~]# kill -9 20249
killall、pkill - 根据名字杀死进程
可以使用kill命令杀死指定进程PID的进程
如果要找到我们需要杀死的进程,我们还需要在之前使用ps等命令再配合grep来查找进程
而killall、pkill把这两个过程合二为一,是一个很好用的命令
# 根据服务名称杀死进程
[root@localhost ~]# pkill nginx
[root@localhost ~]# killall nginx
查看某个用户开启的进程
pgrep -l -u 用户名
3.关于HUP信号
在 Unix 的早期版本中,每个终端都会通过 modem 和系统通讯
当用户 logout 时,modem 就会挂断(hang up)电话
同理:当 modem 断开连接时,就会给终端发送 hangup 信号来通知其关闭所有子进程
当用户注销(logout)或者网络断开或者终端关闭(注意:一定是终端整体关闭,不是单纯的exit)时
终端都会收到Linux HUP信号(hangup)信号,然后终端在结束前会关 闭其所有子进程
如果我们想让我们的进程在后台一直运行,不要因为用户注销(logout)或者网络断开或者终端关闭 而一起被关闭,那么我们有2种解决方案
- 方案1:让进程忽略Linux HUP信号
- 方案2:让进程运行在新的会话里,从而成为不属于此终端的子进程,就不会在当前终端挂掉的情 况下一起被带走
① nohup命令
针对方案1,我们可以使用nohup命令,nohup 的用途就是让提交的命令忽略 hangup 信号,该命令 通常与&符号一起使用
nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可
但是 nohup 命令会从终端解除进程的关联,进程会丢掉STDOUT,STDERR的链接
标准输出和标准错误缺省会被重定向到 nohup.out 文件中
一般我们可在结尾加上"&"来将命令同时放入后台运行,也可用">filename 2>&1"来更改缺省的重定向文件名
② setsid命令
针对方案1,我们还可以用setsid命令实现,原理与nohup命令
是一样的
setid是直接将进程的父pid设置成 1,即让运行的进程归属于init的子进程
那么除非init结束,该子进程才会结束,当前进程所在的终端 结束后并不会影响进程的运行
# (终端1)
[darker@localhost ~]$ setsid ping www.baidu.com
[darker@localhost ~]$ PING www.baidu.com (112.80.248.75) 56(84) bytes of data.
64 bytes from 112.80.248.75 (112.80.248.75): icmp_seq=1 ttl=128 time=10.6 ms
64 bytes from 112.80.248.75 (112.80.248.75): icmp_seq=2 ttl=128 time=10.3 ms
64 bytes from 112.80.248.75 (112.80.248.75): icmp_seq=3 ttl=128 time=10.4 ms
...
# (终端2)
[root@localhost ~]# ps -ef | grep [p]ing
darker 20369 1 0 11:58 ? 00:00:00 ping www.baidu.com
③ 在子shell中提交任务
# (终端1)
[darker@localhost ~]$ (ping www.baidu.com &)
# (终端2)
[root@localhost ~]# ps -ef | grep [p]ing
darker 20369 1 0 11:58 ? 00:00:00 ping www.baidu.com
可以看到新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID
因此并不 属于当前终端的子进程,从而也就不会受到当前终端的Linux HUP信号的影响了
④ screen命令
安装screen
[root@localhost ~]# yum install screen -y
方式1:开启一个窗口并用-S指定窗口名,也可以不指定
Screen将创建一个执行shell的窗口。你可以执行任意shell程序,就像在ssh窗口中那样
在该窗口中键入exit则退出该窗口,如果此时,这是该screen会话的唯一窗口,该screen会话退出,否则screen自动切换到前一个窗口
[root@localhost ~]# screen -S darker
方式2:Screen命令后跟执行的命令
Screen创建一个执行vim test.txt的单窗口会话,退出vim将退出该窗口/会话
[root@localhost ~]# screen vim 1.txt
i
:wq
原理分析
screen程序会帮我们管理运行的命令
退出screen,我们的命令还会继续运行
若关闭screen所在的终端,则screen程序的ppid变为1
所以screen不会死掉,对应着它帮我们管理的命令也不会退出测试
重新连接会话
# (终端1)
[root@localhost ~]# screen -S darker
n=1;while true;do echo $n;sleep 1;((n++));done
按下ctrl+a,然后再按下ctrl+d,注意要连贯 手要快
此时可以关闭整个终端,我们的程序并不会结束
# (终端2)
[root@localhost ~]# screen -ls
There is a screen on:
15443.darker (Detached)
1 Socket in /var/run/screen/S-root.
# 重新打开之前的screen了
[root@localhost ~]# screen -r darker
了解
screen发送命令使用了特殊的键组合Ctrl-a
这是因为我们在键盘上键入的信息是直接发送给当前screen窗口,必须用其他方式向screen窗口管理器发出命令
默认情况下,screen接收以C-a开始的命令
这种命令形式在screen中叫做键绑定(key binding)
可以通过C-a ?来查看所有的键绑定,常用的键绑定有
组合键 | 作用 |
---|---|
Ctrl + a + ? | 显示所有键绑定信息 |
Ctrl + a + w | 显示所有窗口列表 |
Ctrl + a Ctrl + a | 切换到之前显示的窗口 |
Ctrl + a + c | 创建一个新的运行shell的窗口并切换到该窗口 |
Ctrl + a + n | 切换到下一个窗口 |
Ctrl + a + p | 切换到前一个窗口(与Ctrl+a+n 相对 |
Ctrl + a + 0..9 | 切换到窗口0..9Ctrl+a Ctrl+a 发送 Ctrl+a 到当前窗口 |
Ctrl + a + d | 暂时断开screen会话 |
Ctrl + a + k | 杀掉当前窗口 |
Ctrl + a + [ | 进入拷贝/回滚模式 |
Screen常用参数选项
选项 | 作用 |
---|---|
-c file | 使用配置文件file,而不使用默认的$HOME/.screenrc |
不开启新的screen会话,而是断开其他正在运行的screen会话 | |
-h num | 指定历史回滚缓冲区大小为num行 |
列出现有screen会话,格式为pid.tty.host | |
-d -m | 启动一个开始就处于断开模式的会话 |
-r [pid.tty.host] | 重新连接一个断开的会话 |
-S sessionname | 创建screen会话时为会话指定一个名字 |
-v | 显示screen版本信息 |
-wipe [match] | 同-list,但删掉那些无法连接的会话 |
-x | 会话共享演示 |
四:查看网络状态
netstat
选项 | 释义 |
---|---|
-t | TCP协议 |
-u | UDP协议 |
-l | Listen 监听 |
-p | PID / Program name 程序名 |
-n | 不反解,不将IP地址解析为主机名,不将端口号解析成协议名(80 -> http) |
# netstat需要先安装net-tools
[root@localhost ~]# yum install net-tools -y
# 查看正在监听的,且使用tcp协议的进程
[root@localhost ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 914/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1007/master
tcp6 0 0 :::22 :::* LISTEN 914/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1007/master
# 监听22端口
[root@localhost ~]# netstat -an |grep :22
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 192.168.50.101:22 192.168.50.1:64684 ESTABLISHED
tcp 0 0 192.168.50.101:22 192.168.50.1:64678 ESTABLISHED
tcp 0 36 192.168.50.101:22 192.168.50.1:64662 ESTABLISHED
tcp 0 0 192.168.50.101:22 192.168.50.1:64733 ESTABLISHED
tcp6 0 0 :::22 :::* LISTEN
五:proc文件系统
简介
/proc
文件系统是一个虚拟文件系统
通过它可以使用一种新的方法在 Linux内核空间和用户间之间进行通信
在 /proc
文件系统中,我们可以将对虚拟文件的读写作为与内核中实体进行通信的一种手段,但是与普通文件不同的是,这些虚拟文件的内容都是动态创建的
cmdline:系统启动时输入给内核命令行参数
cpuinfo:CPU的硬件信息 (型号, 家族, 缓存大小等)
devices:主设备号及设备组的列表,当前加载的各种设备(块设备/字符设备)
dma:使用的DMA通道
filesystems:当前内核支持的文件系统,当没有给 mount(1) 指明哪个文件系统的时候, mount(1) 就依靠该文件遍历不同的文件系统
interrupts :中断的使用及触发次数,调试中断时很有用
ioports I/O:当前在用的已注册 I/O 端口范围
kcore:该伪文件以 core 文件格式给出了系统的物理内存映象(比较有用),可以用 GDB 查探当前内核的任意数据结构。该文件的总长度是物理内存 (RAM) 的大小再加上 4KB
kmsg:可以用该文件取代系统调用 syslog(2) 来记录内核日志信息,对应dmesg命令
kallsym:内核符号表,该文件保存了内核输出的符号定义, modules(X)使用该文件动态地连接和捆绑可装载的模块
loadavg:负载均衡,平均负载数给出了在过去的 1、 5,、15 分钟里在运行队列里的任务数、总作业数以及正在运行的作业总数。
locks:内核锁
meminfo物理内存、交换空间等的信息,系统内存占用情况,对应df命令
misc:杂项
modules:已经加载的模块列表,对应lsmod命令
mounts:已加载的文件系统的列表,对应mount命令,无参数
partitions:系统识别的分区表
slabinfo:sla池信息
stat:全面统计状态表,CPU内存的利用率等都是从这里提取数据。对应ps命令
swaps:对换空间的利用情况
version:指明了当前正在运行的内核版本
# 对/proc目录下每一个目录和文件的大小分别进行汇总
[root@localhost ~]# du -sh /proc/*
0 /proc/1
0 /proc/10
0 /proc/1007
...
查看实例
CPU相关:/proc/cpuinfo
# 查看逻辑CPU的个数
[root@localhost ~]# grep 'processor' /proc/cpuinfo
processor : 0
processor : 1
# 查看物理CPU的个数
[root@localhost ~]# grep 'processor id' /proc/cpuinfo
# 查看CPU核数
[root@localhost ~]# grep 'cpu cores' /proc/cpuinfo
cpu cores : 2
cpu cores : 2
[root@localhost ~]#
# 查看CPU详情信息
[root@localhost ~]# cat /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 165
model name : Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
stepping : 2
microcode : 0xc8
cpu MHz : 2304.000
cache size : 16384 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 arat pku ospke md_clear spec_ctrl intel_stibp flush_l1d arch_capabilities
bogomips : 4608.00
clflush size : 64
cache_alignment : 64
address sizes : 45 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 165
model name : Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
stepping : 2
microcode : 0xc8
cpu MHz : 2304.000
cache size : 16384 KB
physical id : 0
siblings : 2
core id : 1
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 22
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 arat pku ospke md_clear spec_ctrl intel_stibp flush_l1d arch_capabilities
bogomips : 4608.00
clflush size : 64
cache_alignment : 64
address sizes : 45 bits physical, 48 bits virtual
power management:
# 简单查看CPU信息
[root@localhost ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 165
Model name: Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
Stepping: 2
CPU MHz: 2304.000
BogoMIPS: 4608.00
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 16384K
NUMA node0 CPU(s): 0,1
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ssbd ibrs ibpb stibp ibrs_enhanced fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap clflushopt xsaveopt xsavec xgetbv1 arat pku ospke md_clear spec_ctrl intel_stibp flush_l1d arch_capabilities
内存相关:/proc/meminfo
[root@localhost ~]# less /proc/meminfo
less /proc/meminfo
MemTotal: 995696 kB
MemFree: 496584 kB
MemAvailable: 663736 kB
Buffers: 2108 kB
Cached: 277848 kB
SwapCached: 0 kB
Active: 211844 kB
Inactive: 126460 kB
Active(anon): 58892 kB
Inactive(anon): 7356 kB
Active(file): 152952 kB
Inactive(file): 119104 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 2097148 kB
SwapFree: 2097148 kB
Dirty: 16 kB
Writeback: 0 kB
AnonPages: 58364 kB
Mapped: 23720 kB
Shmem: 7880 kB
Slab: 86732 kB
SReclaimable: 45592 kB
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 972 169 484 7 318 648
Swap: 2047 0 2047
内核启动参数:/proc/cmdline
[root@localhost ~]# cat /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.10.0-1160.6.1.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
[root@localhost ~]# uptime
15:49:03 up 3:46, 4 users, load average: 0.12, 0.05, 0.05
注意:卸载/proc后,以下命令都无法使用
free -m
uptime
lscpu
toop
# 取消挂载
[root@localhost ~]# umount /proc -l
# 下面的命令都无法使用了
[root@localhost ~]# free -m
Error: /proc must be mounted
To mount /proc at boot you need an /etc/fstab line like:
proc /proc proc defaults
In the meantime, run "mount proc /proc -t proc"
[root@localhost ~]# uptime
Error: /proc must be mounted
To mount /proc at boot you need an /etc/fstab line like:
proc /proc proc defaults
In the meantime, run "mount proc /proc -t proc"
[root@localhost ~]# lscpu
lscpu: cannot open /proc/cpuinfo: No such file or directory
重新挂载之后
挂载参数 | 描述 |
---|---|
-t proc | 指定文件系统的类型 |
proc | 文件系统,虚拟文件系统 |
/proc | 挂载点 |
# 挂载
[root@localhost ~]# mount -t proc proc /proc/
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 972 169 483 7 319 647
Swap: 2047 0 2047
[root@localhost ~]# uptime
15:54:29 up 3:51, 4 users, load average: 0.08, 0.08, 0.06
[root@localhost ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 165
Model name: Intel(R) Core(TM) i7-10875H CPU @ 2.30GHz
六:管理后台进程
1.什么是后台进程?
通常进程都会在终端前台运行,一旦关闭终端,进程也会随着结束
那么此时我们就希望进程能在后台运行,就是将在前台运行的进程放入后台运行
这样及时我们关闭了终端也不影响进程的正常运行
2.为何要讲进程放入后台运行?
比如:我们此前在国内服务器往国外服务器传输大文件时,由于网络的问题需要传输很久
如果在传输的过程中出现网络抖动或者不小心关闭了终端则会导致传输失败
如果能将传输的进程放入后台,就能解决此类问题了
3.将进程放入后台的工具
早期的时候大家都选择使用&
符号将进程放入后台,然后再使用jobs、bg、fg
等方式查看进程状态,但太麻烦了 也不直观,所以推荐使用screen
① .jobs、bg、fg的使用(强烈不推荐,了解即可)
# 运行程序,让它在后台执行
[root@localhost ~]# sleep 6000 &
[1] 1036
# 将前台的程序挂起(暂停)到后台
[root@localhost ~]# sleep 7000
^Z # 按:Ctrl + Z
[2]+ Stopped sleep 7000
# 查看后台任务
[root@localhost ~]# jobs
[1]- Running sleep 6000 &
[2]+ Stopped sleep 7000
# 让任务2 在后台运行
[root@localhost ~]# bg %2
[2]+ sleep 7000 &
# 让任务1 调回到前台
[root@localhost ~]# fg %1
sleep 6000
# 进程在后台运行,但输出依然在当前终端
[root@localhost ~]# (while :; do date; sleep 2; done)
② screen的使用(强烈推荐!!!)
详情见:三:3.④
七:管道
1.什么是管道
管道是一种通信机制,通常用于进程间的通信(也可通过socket进行网络通信),它表现出来的形式将前面每一个进程的输出(stdout)直接作为下一个进程的输入(stdin)
详细地说,管道操作符号|
,主要用来连接左右两个命令, 将左侧的命令的标准输出, 交给右侧命令的 标准输入
简而言之,就是把前一条命令的结果 作为参数 传给后一条命令
(这个过程有点像数据库的查询)
格式:命令1|命令2|命令3|命令...
2.管道命令仅能处理standard output
,对于standard error output
会予以忽略
less
、more
、head
、tail
都是可以接收standard input的命令,所以他们是管道命令ls
、cp
、mv
并不会接收standard input
的命令,所以他们就不是管道命令了
3.管道流程示意图
4.管道应用示例
# 统计当前/etc/passwd中用户使用的shell类型
[root@localhost ~]# awk -F: '{print $7}' /etc/passwd | sort | uniq -c
7 /bin/bash
1 /bin/sync
1 /sbin/halt
18 /sbin/nologin
1 /sbin/shutdown
# 统计网站的访问情况(如果有的话)
[root@localhost ~]# netstat -an | grep :80 | awk -F":" '{print $8}'| sort | uniq -c
# 打印/dev下带有usb的目录
[root@localhost ~]# ls -l /dev | grep 'usb'
crw-------. 1 root root 247, 0 Nov 28 2020 usbmon0
crw-------. 1 root root 247, 1 Nov 28 2020 usbmon1
crw-------. 1 root root 247, 2 Nov 28 2020 usbmon2
crw-------. 1 root root 247, 3 Nov 28 2020 usbmon3
crw-------. 1 root root 247, 4 Nov 28 2020 usbmon4
5.选取命令:cut、grep
cut:从某一行信息中取出某部分我们想要的信息
语法
cut -d '分隔字符' -f field // 用于分隔字符
cut -c 字符范围
选项
选项 | 释义 |
---|---|
-d | 后面接分隔字符,通常与 -f 一起使用 |
-f | 根据-d 将信息分隔成数段,-f 后接数字 表示取出第几段 |
-c | 以字符为单位取出固定字符区间的信息 |
实例
# 打印/etc/passwd文件中以:为分隔符的第1个字段和第6个字段分别表示用户名和家目录
[root@localhost ~]# cat /etc/passwd | cut -d ':' -f 1,6
root:/root
bin:/bin
daemon:/sbin
...
# 打印/etc/passwd文件中每一行的前10个字符:
[root@localhost ~]# cat /etc/passwd | cut -c 1-10
root:x:0:0
bin:x:1:1:
daemon:x:2
...
cut在处理多空格相连的数据时,比较吃力
grep:分析一行信息,如果其中有我们需要的信息,就将该行拿出来(模糊匹配/包含)
语法
grep [-acinv] [--color=auto] '查找字符串' filename
选项
选项 | 释义 |
---|---|
-a | 将binary文件 以text文件 的方式查找数据 |
-c | 计算找到 '查找字符串'的次数 |
-i | 忽略大小写的不同 |
-n | 输出行数 |
-v | 反向选择,显示没有查找内容的行 |
--color=auto | 将找到的关键字部分加上颜色显示(其实...不加也可以关键字高亮...) |
实例
# 取出/etc/passwd目录中 包含user的行
[root@localhost ~]# cat /etc/passwd | grep -n 'user'
19:tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
26:user01:x:2021:2021::/home/user01:/bin/bash
27:user02:x:2022:2022::/home/user02:/bin/bash
# 统计/etc/passwd目录中 包含user的行数
[root@localhost ~]# cat /etc/passwd | grep -n -c 'user'
3
# 取出/etc/passwd目录中 不包含user的行
[root@localhost ~]# cat /etc/passwd | grep -n -v 'user'
1:root:x:0:0:root:/root:/bin/bash
2:bin:x:1:1:bin:/bin:/sbin/nologin
3:daemon:x:2:2:daemon:/sbin:/sbin/nologin
4:adm:x:3:4:adm:/var/adm:/sbin/nologin
5:lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6:sync:x:5:0:sync:/sbin:/bin/sync
7:shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
# 统计/etc/passwd目录中 不包含user的行数
[root@localhost ~]# cat /etc/passwd | grep -n -v -c 'user'
25
4.排序命令:sort
、wc
、uniq
sort:排序
语法
sort [-fbMnrtuk] [file or stdin]
选项
选项 | 释义 |
---|---|
-f | 忽略大小写的差异,例如 A 与a 视为编码相同 |
-b | 忽略最前面的空格部分 |
-M | 以月份的名字来排序,例如JAN, DEC 等等的排序方法 |
-n | 使用『纯数字』进行排序默认是以文字型态来排序的 |
-r | 反向排序 |
-u | 就是uniq ,相同的资料中,仅出现一行代表 |
-t | 分隔符号,预设是用[tab] 键来分隔 |
-k | 以哪个区间(field) 来进行排序的意思 |
实例
# 对 /etc/passwd的账号进行排序(默认以第1个字段为参数)
[root@localhost ~]# cat /etc/passwd | sort
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
ben:x:1001:1001::/home/ben:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
darker:x:1000:1000::/home/darker:/bin/bash
dbus:x:81:81:System message bus:/:/sbin/nologin
eve:x:1002:1002::/home/eve:/bin/bash
# 通过/etc/passwd 第5列来进行排序
[root@localhost ~]# cat /etc/passwd | sort -t ':' -k 5
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
bin:x:1:1:bin:/bin:/sbin/nologin
...
uniq:去重
语法
uniq [-ic]
选项
选项 | 释义 |
---|---|
-i | 忽略大小写的不同 |
-c | 进行计数 |
实例
# 使用 last 取出历史登录信息的账号,排序,去重
[root@localhost ~]# last | cut -d ' ' -f 1 | sort | uniq -c
1
5 darker
1 nancy
12 reboot
31 root
1 wtmp
wc:统计
语法
wc [-lwm]
选项
选项 | 释义 |
---|---|
-l | 仅列出行 |
-w | 仅列出多少字(英文单字) |
-m | 多少字符 |
实例
# 查看etc/passwd中有多少账号
[root@localhost ~]# cat /etc/passwd | wc -l
28
# 计算最近登录系统的人次
[root@localhost ~]# last | grep [a-zA-Z] | grep -v 'wtmp' | wc -l
49
# 查看某个文件的行数 字数 字符数
[root@localhost ~]# cat /etc/passwd | wc
28 50 1320
5.双向重定向命令:tee
在数据流的处理过程中将某段信息保存下来,使其 既能输出到屏幕 又能保存到某一个文件中
语法
tee [-a] file
选项
选项 | 释义 |
---|---|
-a | 以累加的方式,将数据加入file中 |
实例
# 先查看当前目录的信息(空空如也)
[root@localhost ~]# ls -l
total 0
# 查询最近用户登录情况(屏幕只显示第一段内容),并将其保存到文件:info.txt中
[root@localhost ~]# last | tee info.txt | cut -d ' ' -f 1
root
reboot
root
...
# 再次先查看当前目录的信息(产生了info.txt文件)
[root@localhost ~]# ls -l
total 4
-rw-r--r--. 1 root root 3811 Nov 27 20:52 info.txt
# 查看info.txt
[root@localhost ~]# last | tee info.txt | cut -d ' ' -f 1
root pts/0 192.168.50.1 Sat Nov 28 00:15 still logged in
reboot system boot 3.10.0-1160.6.1. Sat Nov 28 00:15 - 20:52 (-3:-23)
root pts/1 192.168.50.1 Fri Nov 27 12:20 - down (03:55)
root pts/9 192.168.50.1 Fri Nov 27 12:07 - down (04:08)
root pts/8 192.168.50.1 Fri Nov 27 12:07 - down (04:08)
root pts/7 192.168.50.1 Fri Nov 27 12:06 - 12:07 (00:01)
...
如果文件已存在 就会覆盖,不存在 则会创建
加上
-a
参数则会累加
6.xargs参数传递
主要让一些不支持管道的命令
可以使用管道技术
# 查询cat所在的目录,显示详情信息
[root@localhost ~]# which cat | xargs ls -l
-rwxr-xr-x. 1 root root 54080 Nov 17 06:24 /usr/bin/cat
# 显示之前删除了哪些文件
[root@localhost ~]# ls | xargs rm -fv
removed ‘anaconda-ks.cfg’
removed ‘info.txt’