- 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。
- 可能会用到的资料有如下所示,下载链接见文末:
- 《鸟哥的Linux私房菜 基础学习篇 第四版》1
- 《鸟哥的Linux私房菜 服务器架设篇 第三版》2
- 《韩顺平_2021图解Linux全面升级》3
本章首先来解释两个基本概念——“程序”和“进程”。如上图所示,“程序”就是一段代码,当运行起来时就会加载到内存中,于是就成为一个“进程”。也就是说,“程序”是静态的概念,“进程”是动态的概念。
于是在Linux中,每个执行的程序都称为一个进程,并且每个进程都分配有一个ID号(PID, 进程号)。每个进程都可能以两种方式存在的——前台与后台:“前台进程”就是占有用户屏幕,可以进行交互操作的进程;“后台进程”则是实际在运行,但不会再屏幕显示的进程,通常使用后台方式执行,如用mysql
操作数据库等。以下图所示的QQ软件举例,两台电脑上的QQ用户显然不能直接主机对主机通信,而是要首先将消息发送到QQ后台的服务器中进行转发,这种看不见的进程操作就是“后台进行”;而两台主机的用户都可以在各自的主机屏幕上发送/接收消息,这个显示在屏幕上支持交互操作的进程就是“前台进程”。值得一提的是,系统服务一般都是以“后台进程”的方式存在,而且都会常驻在系统中,直到关机才才结束。
那既然“进程”就是执行的“程序”,由父程序可以调用子函数实现功能,显然进程也有“父进程”和“子进程”:若一个进程是多进程,也就是该进程可以创建“子进程”,那么这个进程就称为“父进程”。如上图所示,每次Linux系统启动时会调用systemd
进程,在随后的过程中,其会创建sshd
、systemd-journald
、lvmetad -f
等一系列子进程,而root用户登录时sshd
进程又会创建子进程sshd: root@pts/1
。于是,sshd: root@pts/1
的父进程就是sshd
进程,而sshd
等一系列进程的父进程就是systemd
进程。
Linux进程管理中一个非常重要的操作就是查找某个进程的父进程,因为在kill
一个父进程的同时,也可以选择是否也一并kill
掉其下所有子进程。
注:14.1.4小节【案例2】演示了如何查看父进程的进程号(PPID)。
注:kill
将具体在14.1.5小节再具体介绍。
本小节来介绍一个本章经常见到的Linux后台进程:sshd
进程、network
进程。
sshd
进程:SSHD(Secure Shell Daemon, 安全外壳守护进程)是在Linux系统上运行的一个守护进程,用于支持在不安全的网络环境下进行加密的远程登录。sshd
进程决定了我们是否可以通过Xhsell远程登录到Linux上。network
进程:是一个核心网络配置的进程,它包含了 Linux 网络设置中的所有业务代码,包括网络命令,网络状态监测,网络配置的重启等等。network
决定了其他主机能否与该Linux系统ping
通,显然也决定了Xhsell能否远程连接到Linux上。更多介绍查看“Linux运维小知识之10个必须掌握的系统进程”。
ps
前面三个小节介绍了操作系统中“进程”的概念。那该如何查看Linux系统中正在执行的进程以及它们执行的状况?答案是ps
指令:
# 基本语法-ps
ps [选项] # 查看正在执行的进程
# 常用选项-ps
-a 显示当前终端的所有进程信息
-u 以用户的格式显示进程信息
-x 显示后台进程运行的参数
-e 显示所有进程
-f 全格式
常用的ps
组合选项有两种:ps -aux
和ps -ef
,这两者的输出结果差别不大,但展示风格不同。ps -aux
是BSD风格,而ps -ef
是System V风格,具体的区别可以查看CSDN博文“ps -ef和ps -aux的区别”。下面结合具体实例一一介绍这两种风格的各个不同选项:
【案例1】使用ps -aux
查看当前系统进程,并找出sshd
进程。
[root@CentOS76 ~]# ps -aux | more
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 194088 7344 ? Ss 11:14 0:03 /usr/lib/systemd/systemd --switc
hed-root --system --deserialize 22
root 2 0.0 0.0 0 0 ? S 11:14 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< 11:14 0:00 [kworker/0:0H]
root 6 0.0 0.0 0 0 ? S 11:14 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S 11:14 0:00 [migration/0]
root 8 0.0 0.0 0 0 ? S 11:14 0:00 [rcu_bh]
root 9 0.0 0.0 0 0 ? S 11:14 0:01 [rcu_sched]
root 10 0.0 0.0 0 0 ? S< 11:14 0:00 [lru-add-drain]
# 中间有非常多进程,省略掉了
root 8273 0.0 0.0 108052 352 ? S 16:11 0:00 sleep 60
root 8274 0.0 0.0 157532 1920 pts/1 R+ 16:12 0:00 ps -aux
root 8275 0.0 0.0 110584 976 pts/1 S+ 16:12 0:00 more
# 现在过滤一下sshd进程
[root@CentOS76 ~]# ps -aux | grep sshd
root 1197 0.0 0.0 112900 4300 ? Ss 11:14 0:00 /usr/sbin/sshd -D
root 8005 0.0 0.0 160988 5648 ? Ss 15:51 0:00 sshd: root@pts/1
root 8396 0.0 0.0 112828 972 pts/1 S+ 16:23 0:00 grep --color=auto sshd
# 上面第一条是真正执行的进程,第二条是Xshell登录到sshd的指令,最后一条是刚输入的grep查询指令。
# ps显示的信息选项-aux (System V显示风格)
USER 进程执行用户
PID 进程号
%CPU 进程占用CPU的百分比
%MEM 进程占用物理内存的百分比
VSZ 进程占用的虚拟内存大小(单位:KB)
RSS 进程占用的物理内存大小(单位:KB)
TTY 终端名称,一般缩写
STAT 当前进程运行状态,下面列出常见的进程状态:
S-睡眠。
s-表示该进程是会话的先导进程,。
N-表示进程拥有比普通优先级更低的优先级。
R-正在运行。
D-短期等待。
Z-僵死进程,需要定时清除。
T-被跟踪或者被停止。
START 进程执行开始时间
TIME 进程占用CPU的总时间
COMMAD 启动进程所用的命令和参数,如果过长会被截断显示
【案例2】使用ps -ef
查看当前系统进程,并找出sshd
进程。
[root@CentOS76 ~]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 11:14 ? 00:00:03 /usr/lib/systemd/systemd --switched-root --syste
root 2 0 0 11:14 ? 00:00:00 [kthreadd]
root 4 2 0 11:14 ? 00:00:00 [kworker/0:0H]
root 6 2 0 11:14 ? 00:00:00 [ksoftirqd/0]
root 7 2 0 11:14 ? 00:00:00 [migration/0]
root 8 2 0 11:14 ? 00:00:00 [rcu_bh]
root 9 2 0 11:14 ? 00:00:01 [rcu_sched]
root 10 2 0 11:14 ? 00:00:00 [lru-add-drain]
# 中间有非常多进程,省略掉了
root 8005 1197 0 15:51 ? 00:00:00 sshd: root@pts/1
root 8009 8005 0 15:51 pts/1 00:00:00 -bash
root 8484 2 0 16:30 ? 00:00:00 [kworker/4:0]
root 8559 853 0 16:38 ? 00:00:00 sleep 60
root 8562 8009 0 16:39 pts/1 00:00:00 ps -ef
[root@CentOS76 ~]# ps -ef | grep sshd
root 1197 1 0 11:14 ? 00:00:00 /usr/sbin/sshd -D
root 8005 1197 0 15:51 ? 00:00:00 sshd: root@pts/1
root 8510 8009 0 16:33 pts/1 00:00:00 grep --color=auto sshd
# ps显示的信息选项-ef (BSD显示风格)
UID 用户ID
PID 进程ID
PPID 父进程ID
C CPU用于计算执行优先级的因子。
数值越大,表明进程是CPU密集型运算,执行优先级会降低。
数值越小,表明进程是I/O密集型运算,执行优先级会提高。
STIME 进程启动的时间
TTY 完整的终端名称
TIME CPU时间
CMD 启动进程所用的命令和参数
上述显示sshd进程的PID为1197,sshd父进程的PPID为1。显然相比于ps -aux
,ps -ef
还可以查看其父进程的进程号。
kill
/killall
若是某个进程执行一半需要停止时,或是已消了很大的系统资源时,此时可以考虑停止该进程,于是便可以考虑使用kill
/killall
。通常,终止单个进程用kill
,快速终止某个进程及其所有的子进程用killall
:
# 基本语法-kill
kill [选项] 进程号 # 通过进程号杀死进程
killall 进程名称 # 通过进程名称杀死进程,也支持通配符,在系统因负载过大而变得很慢时可以快速清理内存。
# 常用选项-kill/killall
-9 表示强迫进程立即停止,防止系统为了安全屏蔽kill某些进程
下面展示四个应用案例:
注:这四个应用案例都在虚拟机的图形界面终端执行。
【案例1】踢掉某个非法登录用户tom。
# 先通过Xshell登录tom用户,然后在虚拟机图形界面输入以下指令:
[root@CentOS76 ~]# ps -aux | grep sshd
root 1197 0.0 0.0 112900 4300 ? Ss 11:14 0:00 /usr/sbin/sshd -D
root 8776 0.2 0.0 160988 5580 ? Ss 16:56 0:00 sshd: tom [priv]
tom 8780 0.0 0.0 160988 2372 ? S 16:56 0:00 sshd: tom@pts/2
root 8871 0.0 0.0 112828 968 pts/0 R+ 16:56 0:00 grep --color=auto sshd
# priv是先导进程,于是tom登录的进程号就是8776
[root@CentOS76 ~]# kill 8776
# 该指令输入完毕后,Xshell登录的tom用户立刻被强制退出。
【案例2】终止远程登录服务sshd,然后再重启sshd服务。
# 查看sshd的进程号
[root@CentOS76 ~]# ps -aux | grep sshd
root 1197 0.0 0.0 112900 4300 ? Ss 11:14 0:00 /usr/sbin/sshd -D
root 8960 0.0 0.0 112828 972 pts/0 S+ 17:01 0:00 grep --color=auto sshd
# sshd的进程号是1197
[root@CentOS76 ~]# kill 1197
# 此时Xshell无法登录,并且再查询就发现没有sshd进程了
[root@CentOS76 ~]# ps -aux | grep sshd
root 8993 0.0 0.0 112824 972 pts/0 S+ 17:04 0:00 grep --color=auto sshd
# 下面重启sshd服务
[root@CentOS76 ~]# /bin/systemctl start sshd.service
# 此时Xshell可以登录了,并且再查询发现sshd重启,新的进程号为9015
[root@CentOS76 ~]# ps -aux | grep sshd
root 9015 0.0 0.0 112900 4304 ? Ss 17:05 0:00 /usr/sbin/sshd -D
root 9023 0.0 0.0 112824 968 pts/0 S+ 17:05 0:00 grep --color=auto sshd
【案例3】使用killall
终止多个文本编辑器gedit。
# 在/home下创建多个文件
[root@CentOS76 home]# cd /home
[root@CentOS76 home]# touch pig.txt
[root@CentOS76 home]# touch cat.txt
[root@CentOS76 home]# touch fox.txt
# 然后在图形界面依次打开这三个txt文件
[root@CentOS76 home]# killall gedit
# 可以发现文本编辑器的三个窗口都被关闭了
【案例4】强制杀掉一个终端。
# 在图形界面的桌面打开两个终端,在其中一个终端查询另个终端的进程号
[root@CentOS76 ~]# ps -aux | grep bash
root 853 0.0 0.0 115408 956 ? S 11:14 0:00 /bin/bash /usr/sbin/ksmtuned
root 2051 0.0 0.0 72472 776 ? Ss 11:16 0:00 /usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic"
root 9034 0.0 0.0 116760 3292 pts/1 Ss+ 17:05 0:00 -bash
root 9498 0.0 0.0 116972 3288 pts/0 Ss+ 17:29 0:00 bash
root 9540 0.0 0.0 116972 3296 pts/2 Ss 17:29 0:00 bash
root 9593 0.0 0.0 112828 972 pts/2 S+ 17:30 0:00 grep --color=auto bash
# 通过对比启动时间,可以看到当前终端是9540,另一个终端的进程号是9498。
[root@CentOS76 ~]# kill 9498
# 系统以为是误操作,所以置之不理。接下来强制杀掉终端。
[root@CentOS76 ~]# kill -9 9498
# 可以看到另一个终端没了。
[root@CentOS76 ~]# kill -9 9540
# 当前终端也被直接关闭了。
pstree
除了使用ps -ef
可以通过查看PPID来查看父进程,还可以通过查看进程树来查看所有进程的父子关系:
# 基本语法-pstree
pstree [选项] # 可以更加直观的来看进程信息
# 常用选项-pstree
-p 显示进程的PID
-u 显示进程的所属用户
下面展示四个应用案例:
【案例1】以树状的形式显示进程的pid。
[root@CentOS76 ~]# pstree -p
systemd(1)─┬─ModemManager(768)─┬─{ModemManager}(785)
│ └─{ModemManager}(816)
├─NetworkManager(875)─┬─dhclient(4278)
│ ├─{NetworkManager}(879)
│ └─{NetworkManager}(884)
├─VGAuthService(758)
├─abrt-watch-log(778)
├─abrt-watch-log(782)
├─abrtd(777)
├─accounts-daemon(762)─┬─{accounts-daemon}(770)
# 中间有非常多进程,省略掉了
├─vmtoolsd(759)─┬─{vmtoolsd}(814)
│ └─{vmtoolsd}(2623)
├─vmtoolsd(2418)─┬─{vmtoolsd}(2455)
│ ├─{vmtoolsd}(2457)
│ └─{vmtoolsd}(4043)
├─wpa_supplicant(1598)
└─xdg-permission-(2143)─┬─{xdg-permission-}(2144)
└─{xdg-permission-}(2146)
【案例2】请你树状的形式进程的用户名
为了演示效果更加明显,建议使用Xhsell远程登陆root用户、tom用户、jack用户并在jack用户中执行下面的指令。
[tom@CentOS76 ~]$ pstree -u
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager─┬─dhclient
│ └─2*[{NetworkManager}]
├─VGAuthService
├─abrt-dbus───3*[{abrt-dbus}]
├─2*[abrt-watch-log]
├─abrtd
├─accounts-daemon───2*[{accounts-daemon}]
# 中间有非常多进程,省略掉了
├─smartd
├─sshd─┬─sshd───bash # 这一行是root用户
│ ├─sshd───sshd(tom)───bash # 这一行是tom用户
│ └─sshd───sshd(jack)───bash───pstree # 这一行是jack用户
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tracker-store───7*[{tracker-store}]
├─tuned───4*[{tuned}]
├─udisksd───4*[{udisksd}]
├─upowerd───2*[{upowerd}]
├─vmhgfs-fuse───8*[{vmhgfs-fuse}]
├─vmtoolsd───2*[{vmtoolsd}]
├─vmtoolsd───3*[{vmtoolsd}]
├─wpa_supplicant
└─xdg-permission-───2*[{xdg-permission-}]
其实本节也成为“服务(service)管理指令”,但“服务”本质就是“后台进程”,所以为了名称的连贯性我将本节改名为“后台进程管理指令”。于是本节中所有的“后台进程”和“服务”等价。
自2014年7月7日正式发布CentOS7(RHEL7)以来,系统中的后台进程从原来的由systemV
管理机制升级到了systemd
。要想查看所有的后台进程,可以直接在终端输入setup-->选择“系统服务”回车
,如下图:
- 使用
tab
键和↑↓
方向键切换选项,Enter
键确认选项。- 有“星号”的服务会随着Linux系统的启动而自启,没有带“星号”的则需要手动启动。
- 要想去掉星号,需要将光标移动到相应的星号上,按空格键取消星号,再按一次添加星号。
- 可以看到SysV管理的服务只有两个,剩下的所有服务都在
systemd
中管理。更多关于systemV和systemd的内容可以查看CSDN博客:
- 2021-01的文章:“systemV和systemd的理解”
- 2015-09的文章:“system V与systemd-”
如上图所示,Linux系统在开机时会检查运行级别,进而启动当前运行级别对应的服务,所以“运行级别”是Linux系统中非常重要的概念,当前前几章也反复的介绍过。如下表,Linux系统有7种运行级别(runlevel),并且常用的级别就是3和5。CentOS7以前需要在/etc/inittab
文件中手动调整,而在CentOS7及其以后的版本主要对最常用的运行级别3、运行级别5进行了简化,可以直接使用指令进行更改:
# 运行级别代称
multi-user.target # 运行级别3代称
graphical.target # 运行级别5代称
# 查看当前的默认运行级别
systemctl get-default
# 修改默认运行级别
systemctl set-default [TARGET].target
# 下面是两个例子
systemctl set-default multi-user.target # 修改默认运行级别为3
systemctl set-default graphical.target # 修改默认运行级别为5
级别 | 描述 |
---|---|
0 | 停机状态。系统默认运行级别不能设置为0,否则系统不能正常启动。 |
1 | 单用户状态。此状态仅 root 用户可登录,用于系统维护,禁止远程登录,相当于 Windows 下的安全模式。 |
2【少见】 | 多用户状态(无NFS)。没有网络服务。 |
3【最常见】 | 完整的多用户状态(有NFS)。有网络服务,登录后进入控制台命令行模式。 |
4【少见】 | 系统未使用,保留一般不用,在一些特殊情况下可以用它来做一些事情。 例如在笔记本电脑的电池用尽时,可以切换到这个模式来做一些设置。 |
5【常见】 | 图形化模式,登陆后进入图形GUI模式或GNOME、KDE图形化界面,如X Window系统。 |
6 | 系统正常关闭并重启。默认运行级别不能设为6,否则不能正常启动,而是会一直开机重启开机重启。 |
service
“后台进程”通常都会监听某个端口,等待其它程序的请求,比如(mysqld, sshd防火墙等),因此“后台进程”又通常被称为“守护进程”,是Linux中非常重要的知识点。通常来说,“找端口”本质上就是找监听该端口的后台进程。关闭某个后台进程,相应的端口监听也就会停止。下图展示了后台进程监听端口的示意图:
在早期版本的Linux中,常使用service
管理指令来对后台进程进行启动、停止、重启、重载、查看状态等。但是在CentOS7.0后service
指令被弱化,很多服务不再使用service
,而是systemctl
指令进行管理(见14.2.4节)。并且在CentOS7.0后,被service
指令管理的服务主要在/etc/init.d
查看。下面是service
的基本语法及查看/etc/init.d
文件:
# 基本语法-service
service 服务名 [start | stop| restart | reload | status]
# 查看/etc/init.d文件
[root@CentOS76 ~]# ll /etc/init.d/
总用量 40
-rw-r--r--. 1 root root 18281 5月 22 2020 functions
-rwxr-xr-x. 1 root root 4569 5月 22 2020 netconsole # 绿色高亮
-rwxr-xr-x. 1 root root 7928 5月 22 2020 network # 绿色高亮
-rw-r--r--. 1 root root 1160 10月 2 2020 README
# 可以看到被service管理的后台进程就只有上面两个绿色高亮的。
[root@CentOS76 ~]# service network status
已配置设备:
lo ens33
当前活跃设备:
lo ens33 virbr0
[root@CentOS76 ~]# service netconsole status
未加载 netconsole 模块
下面展示一个应用案例:
【案例1】使用service
指令查看、关闭、启动network后台进程。
注:以下都在虚拟机图形界面的终端进行操作,因为网络服务断掉后无法使用Xhsell。
[root@CentOS76 ~]# service network status
已配置设备:
lo ens33
当前活跃设备:
lo ens33 virbr0
[root@CentOS76 ~]# service network stop
Stopping network (via systemctl): [ 确定 ]
# 此时可以发现Xhsell界面无法输入指令,也无法重新连接。
[root@CentOS76 ~]# service network start
Starting network (via systemctl): [ 确定 ]
# 稍等一会就会发现Xshell又可以连接了。
chkconfig
那除了查看后台进程,肯定也想设置某个后台进程是否开机自启,就像是14.2.1节中的 “星号*” 代表该服务开机自启一样。于是便有了指令chkconfig
。但是和service
指令相同,chkconfig
指令也是一个早期版本的指令,在CentOS7.0之后被弱化,Centos7.0后很多服务使用systemctl
管理(见14.2.4节)。所以和service
指令相同,chkconfig
指令能管理的服务也是在/etc/init.d
查看。
通过chkconfig
命令可以给每个服务分别设置在各个运行级别上是否自启动,比如可以通过chkconfig
设置network
服务在运行级0是否自启动、在运行级别1是否自启动。另外,chkconfig
重新设置服务后自启动或关闭,需要重启机器reboot生效。下面是chkconfig
的基本语法:
chkconfig --list [| grep xxx] # 查看所有服务的开机自启情况,grep过滤服务
chkconfig 服务名 --list # 查看某服务的开机自启情况
chkconfig --level 5 服务名 on/off # 设置某服务在运行级别5是否自启动
下面展示一个应用案例:
【案例1】使用chkconfig
查看network
服务在各个运行级别的开机自启情况。
[root@CentOS76 ~]# chkconfig --list
注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。
要列出 systemd 服务,请执行 'systemctl list-unit-files'。
查看在具体 target 启用的服务请执行
'systemctl list-dependencies [target]'。
netconsole 0:关 1:关 2:关 3:关 4:关 5:关 6:关
network 0:关 1:关 2:开 3:开 4:开 5:开 6:关
[root@CentOS76 ~]# chkconfig --list | grep network
注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。
要列出 systemd 服务,请执行 'systemctl list-unit-files'。
查看在具体 target 启用的服务请执行
'systemctl list-dependencies [target]'。
network 0:关 1:关 2:开 3:开 4:开 5:开 6:关
【案例2】使用chkconfig
设置network
在运行级别3的自启动关闭,然后再开启。
[root@CentOS76 ~]# chkconfig --level 5 network off
[root@CentOS76 ~]# chkconfig --list | grep network
注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。
要列出 systemd 服务,请执行 'systemctl list-unit-files'。
查看在具体 target 启用的服务请执行
'systemctl list-dependencies [target]'。
network 0:关 1:关 2:开 3:开 4:开 5:关 6:关
[root@CentOS76 ~]#
[root@CentOS76 ~]#
[root@CentOS76 ~]# chkconfig --level 5 network on
[root@CentOS76 ~]# chkconfig --list | grep network
注:该输出结果只显示 SysV 服务,并不包含
原生 systemd 服务。SysV 配置数据
可能被原生 systemd 配置覆盖。
要列出 systemd 服务,请执行 'systemctl list-unit-files'。
查看在具体 target 启用的服务请执行
'systemctl list-dependencies [target]'。
network 0:关 1:关 2:开 3:开 4:开 5:开 6:关
systemctl
本小节标注了一个*号,表示本节很重要,是本章的重点。正如前两小节所提及的,systemctl
管理指令是当前CentOS系统最常用的服务管理指令,其功能最强大。systemctl
指令可以管理在/usr/lib/systemd/system
下所有的服务,几乎囊括了CentOS系统中所有的指令。下面是systemctl的基本语法:
# 基本语法-systemctl
systemvtl [选项] {命令}
# 常用实例-systemctl
systemctl [start | stop | restart | status] 服务名 # 设置某服务的当前状态,但注意重启后还是恢复成默认状态
systemctl list-unit-files [| grep 服务名] # 查看某服务的开机自启状态,grep可以进行过滤
systemctl enable 服务名 # 设置某服务的开机自启状态
systemctl disable 服务名 # 关闭某服务的开机自启状态
systemctl is-enabled 服务名 # 查看某服务是否开启了开机自启
前面用chkconfig
可以修改到某个指令在某个运行级别下是否自启动,那这个systemctl
怎么没有提及呢?这是因为CentOS7之后做出了简化,所以上述的操作默认都是对运行级别3/5同时进行操作。
应用案例:
【案例1】查看当前“防火墙”服务的状况,关闭防火墙和重启防火墙。
# 1.首先查询一下防火墙服务的名称
[root@CentOS76 ~]# ll /usr/lib/systemd/system | grep fire
-rw-r--r--. 1 root root 657 10月 1 2020 firewalld.service
# 防火墙服务的名称为firewalld.service,也可以简化写成firewalld
# 2.查看防火墙服务firewalld.service的状态
[root@CentOS76 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since 四 2023-07-13 19:50:00 CST; 1 weeks 5 days ago
Docs: man:firewalld(1)
Main PID: 857 (firewalld)
Tasks: 2
CGroup: /system.slice/firewalld.service
└─857 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
7月 13 19:50:00 CentOS76 systemd[1]: Starting firewalld - dynamic firewall daemon...
7月 13 19:50:00 CentOS76 systemd[1]: Started firewalld - dynamic firewall daemon.
7月 13 19:50:00 CentOS76 firewalld[857]: WARNING: AllowZoneDrifting is enabled. This is con...ow.
Hint: Some lines were ellipsized, use -l to show in full.
# 3.关闭并查看防火墙服务firewalld.service的状态
[root@CentOS76 ~]# systemctl stop firewalld
[root@CentOS76 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: inactive (dead) since 三 2023-07-26 10:24:47 CST; 3s ago
Docs: man:firewalld(1)
Process: 857 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
Main PID: 857 (code=exited, status=0/SUCCESS)
7月 13 19:50:00 CentOS76 systemd[1]: Starting firewalld - dynamic firewall daemon...
7月 13 19:50:00 CentOS76 systemd[1]: Started firewalld - dynamic firewall daemon.
7月 13 19:50:00 CentOS76 firewalld[857]: WARNING: AllowZoneDrifting is enabled. This is con...ow.
7月 26 10:24:41 CentOS76 systemd[1]: Stopping firewalld - dynamic firewall daemon...
7月 26 10:24:47 CentOS76 systemd[1]: Stopped firewalld - dynamic firewall daemon.
Hint: Some lines were ellipsized, use -l to show in full.
# 4.重启并查看防火墙服务firewalld.service的状态
[root@CentOS76 ~]# systemctl start firewalld
[root@CentOS76 ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since 三 2023-07-26 10:25:06 CST; 2s ago
Docs: man:firewalld(1)
Main PID: 14457 (firewalld)
Tasks: 2
CGroup: /system.slice/firewalld.service
└─14457 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...me.
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...me.
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
7月 26 10:25:06 CentOS76 firewalld[14457]: WARNING: COMMAND_FAILED: '/usr/sbin/iptables -w1...?).
Hint: Some lines were ellipsized, use -l to show in full.
细节讨论:
- 关闭或者启用防火墙后,立即生效。
- 这种方式只是临时生效,当重启系统后,还是回归以前对服务的设置。
- 如果希望设置某个服务自启动或关闭永久生效,要使用
systemctl [enable|disable] 服务名
。
那如何只打开单个端口而不用关闭整个防火墙呢?下一小节介绍。
firewall
首先来介绍一下什么是防火墙。如上图所示,防火墙的作用就相当于“护卫”,决定每一个访问Linux系统的请求是否通过。若关闭防火墙后,则所有的访问都会被允许,甚至是恶意访问。在真正的生产环境,往往需要将防火墙打开,但若直接一棒子打死所有请求都不通过,那么正常的外部请求数据包就不能与Linux服务器的端口进行通讯。这时就需要打开防火墙的指定端口,语法如下:
# firewall指令
firewall-cmd --permanent --add-port=端口号/协议 # 打开端口
firewall-cmd --permanent --remove-port=端口号/协议 # 关闭端口
firewall-cmd --reload # 注意上述打开/关闭端口后,重新载入才能生效!!
firewall-cmd --query-port=端口/协议 # 查询端口是否开放
下面展示两个应用案例:
【案例1】直接关闭整个防火墙,验证telnet能否远程登录到Linux系统的111端口。
【提示】由于Xshell只能远程登录Linux,连接的是sshd进程的22端口,要想连接Linux的其他端口便无能为力。于是为了连接Linux系统下的其他端口,以验证防火墙已开放了某个端口的连接权限,可以使用Windows自带的远程连接工具telnet。Windows下Telnet客户端默认关闭,开启方法见“win11开启telnet服务”。
# 使用Linux的终端
netstat -anp | more # 查看目前有哪些端口处于监听状态,然后选择了111端口
# 使用Windows的cmd客户端
telnet Linux的IP地址 111 # 访问Linux下的111端口,此时是失败
# 使用Linux的终端
systemctl stop firewalld # 关闭防火墙
# 使用Windows的cmd客户端
telnet Linux的IP地址 111 # 访问Linux下的111端口,此时就会成功
【案例2】只关闭防火墙对于访问111端口的拦截,验证telnet能否远程登录到Linux系统的111端口。
# 首先在Xshell登录root用户,查询端口号111对应的协议
[root@CentOS76 ~]# netstat -anp | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 761/rpcbind
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 9015/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1201/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1368/master
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 12376/sshd: root@p
t
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 13232/sshd: root@p
t
tcp 0 0 192.168.137.128:22 192.168.137.1:64365 ESTABLISHED 13232/sshd: root@p
t
tcp 0 0 192.168.137.128:22 192.168.137.1:63623 ESTABLISHED 12376/sshd: root@p
t
tcp6 0 0 :::111 :::* LISTEN 761/rpcbind
# 下面还有很多就不展示了
# 第一列“Proto”就是协议,“Local Address”最后一个冒号后就是端口号
# 下面使用Windows的cmd客户端,验证此时telnet失败
PS C:\Users\14751> telnet 192.168.137.128 111
正在连接192.168.137.128...无法打开到主机的连接。 在端口 111: 连接失败
# 返回Xshell客户端,关闭111端口防火墙
[root@CentOS76 ~]# firewall-cmd --permanent --add-port=111/tcp
success
[root@CentOS76 ~]# firewall-cmd --reload
success
[root@CentOS76 ~]# firewall-cmd --query-port=111/tcp
yes
# 然后回到Windows的cmd客户端,验证此时telnet成功
PS C:\Users\14751> telnet 192.168.137.128 111 # 直接进入。输入ctrl+]、再输入quit退出telnet
# 返回Xshell客户端,打开111端口防火墙
[root@CentOS76 ~]# firewall-cmd --permanent --remove-port=111/tcp
success
[root@CentOS76 ~]# firewall-cmd --reload
success
[root@CentOS76 ~]# firewall-cmd --query-port=111/tcp
no
# 然后回到Windows的cmd客户端,验证此时telnet又被失败了
PS C:\Users\14751> telnet 192.168.137.128 111
正在连接192.168.137.128...无法打开到主机的连接。 在端口 111: 连接失败
实际上Linux系统的防火墙非常强大,这里老韩只介绍了最简单的功能。
top
前面已经介绍了ps
指令,可以查看系统所有的进程,甚至也可以查看每个进程占用CPU和内存的占用情况(ps -aux
)。但是ps
指令最大的缺点就是,ps
的进程监控是静态的!那Linux下是否存在一种动态的监控指令,类似于Windows系统的“任务管理器-性能”窗口,可以实时的监控系统性能的变化呢?答案就是top
指令。top
与ps
命令很相似,都用来显示正在执行的进程,但top
与ps
最大的不同之处,在于top
指令是一种动态的监控,在执行一段时间后可以更新正在运行的的进程监控。
# 基本语法-top
top [选项]
# 选项说明-top
-d 秒数 指定top命令每隔几秒更新。默认是3秒
-i 使top不显示任何闲置或者僵死进程。
-p 通过指定监控进程ID来仅仅监控某个进程的状态。
# 交互操作-top(显示界面如何排序)
P 以CPU使用率排序,默认就是此项
M 以内存的使用率排序
N 以PID排序
q 退出top
上图是top
动态监控进程的窗口,各个内容的含义解释如下:
# top显示的信息选项
PID 进程的标识符
USER 运行进程的用户名
PR 进程的优先级
NI 进程的优先级调整值
VIRT 进程使用的虚拟内存大小
RES 常驻内存。进程实际使用的物理内存大小
SHR 共享内存。进程共享的内存大小
%CPU 进程占用 CPU 的使用率
%MEM 进程占用内存的使用率
TIME+ 进程的累计 CPU 时间
COMMAD 启动进程所用的命令和参数,如果过长会被截断显示
最后注意:
- 负载值:三个值的平均值大于0.7就是负载较大。
- 因为僵死进程已经死掉了但是还占用内存,所以僵死进程一定要定时清除!
更多关于
top
指令的信息可以查看:
- CSDN博文“CPU状态信息us,sy,ni,id,wa,hi,si,st含义”
- 菜鸟教程“Linux top 命令”
应用实例
【案例1】监视特定用户,比如监控用户tom。
提示:首先登录用户tom,然后回到root用户进行操作。
# 下面是操作步骤:
top # 输入此命令,按回车键,查看执行的进程。
u # 然后输入“u”回车,
tom # 再输入用户名,即可。
# 下面是最终的显示结果,可以看到最终监控到了tom的进程:
Tasks: 311 total, 1 running, 305 sleeping, 5 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.9 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 8154928 total, 5032444 free, 1079020 used, 2043464 buff/cache
KiB Swap: 2097148 total, 2097148 free, 0 used. 6771368 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
18708 tom 20 0 160988 2368 1024 S 0.0 0.0 0:00.00 sshd
18709 tom 20 0 116884 3304 1692 S 0.0 0.0 0:00.02 bash
【案例2】终止指定的进程,比如要结束用户tom的登录。
top # 输入此命令,按回车键,查看执行的进程。
k # 然后输入“k”回车。
18709 # 再输入要结束的进程ID号,由上个例子可以看到tom的登录端bash进程ID号为18709。
9 # 输入信号量9,强制删除。
# 此时可以发现用户tom被强制退出了。
【案例3】指定系统状态更新的时间,每隔10秒自动更新(默认是3秒)。
top -d 10 # 终端输入即可
netstat
指令netstat
可以监控系统网络状态,比如哪些进程正在监听哪些端口、有哪些连接已经到达系统。这个命令在工作环境下会频繁使用,因为其可以看到当前网络哪些服务处于监听的状态,而且也可以看到有哪些连接到了Linux系统。若发现系统变慢了,或者某个端口消耗资源很大,或者忽然看到一个未知的监听端口,那很有可能是一个木马程序在监听,所以会频繁使用。
# 基本语法-neustat
netstat [选项]
# 选项说明-netstat
-an 按一定顺序排列输出
-p 显示哪个进程在调用
# 显示信息-netstat
Proto 所使用的网络协议(tcp/tcp6/udp/udp6)
Recv-Q 数据已经在本地接收缓冲,但是还没有recv()
Send-Q 对方没有收到的数据或者说没有Ack的,还是本地缓冲区
Local Address 本地IP:本地端口
Foreign Address 远程IP:远程端口
State 链接状态(监听状态/建立连接状态等)
PID 进程PID号
Program name 程序名字
# netstat -an 演示示例
[root@CentOS76 ~]# netstat -an | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN
tcp 0 36 192.168.137.130:22 192.168.137.1:61775 ESTABLISHED
tcp 0 0 192.168.137.129:22 192.168.137.1:59542 ESTABLISHED
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 ::1:631 :::* LISTEN
tcp6 0 0 ::1:25 :::* LISTEN
tcp6 0 0 ::1:6010 :::* LISTEN
tcp6 0 0 ::1:6011 :::* LISTEN
udp 0 0 0.0.0.0:37462 0.0.0.0:*
udp 0 0 0.0.0.0:931 0.0.0.0:*
udp 0 0 0.0.0.0:5353 0.0.0.0:*
udp 0 0 0.0.0.0:67 0.0.0.0:*
udp 0 0 0.0.0.0:68 0.0.0.0:*
udp 0 0 0.0.0.0:111 0.0.0.0:*
udp 0 0 127.0.0.1:323 0.0.0.0:*
udp6 0 0 :::931 :::*
udp6 0 0 :::111 :::*
udp6 0 0 ::1:323 :::*
raw6 0 0 :::58 :::* 7
# 下面还有很多这里就不演示了
一般来讲,“Local Address”本地地址和“Foreign Address”外部地址。下图给出了本地地址和外部地址的示意图,现在根据上面netstat -an
的演示示例,简单介绍一下本地地址和外部地址:
本地地址:
0.0.0.0:111
:表示监听本地服务器上所有ip的111端口(0.0.0.0
表示所有ip)。127.0.0.1:631
表示监听本机的loopback(回环地址)地址的631端口。:::111
:表示监听本地服务器上所有ip的111端口。前2个冒号是0:0:0:0:0:0:0:0
的缩写,表示本地所有IPv6地址;第3个冒号是IP和端口的分隔符号。- 形如
::1:631
:表示监听IPv6的回环地址的631端口。外部地址:与本地服务器通信的其他主机的IP地址,显示规则和上面本地地址的相同。
192.168.137.130:22
:表示外部地址192.168.137.130
已经和本地端口22建立了连接。更详细可以查看:
- 菜鸟教程“Linux netstat命令”
- 百度文章“每周一个linux命令(netstat)”
- CSDN博客“Linux使用netstat查看网络状态”。
下面展示两个应用案例:
【案例1】使用Xshell同时登录root用户、tom用户,然后在root用户观察tom用户logout
退出时,22端口是否会有一瞬间的超时等待连接状态。
[root@CentOS76 ~]# netstat -an | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN
tcp 0 36 192.168.137.128:22 192.168.137.1:64365 ESTABLISHED
tcp 0 0 192.168.137.128:22 192.168.137.1:52241 ESTABLISHED
tcp6 0 0 :::111 :::* LISTEN
# 下面还有很多就不演示了,主要是看ESTABLISHED两个进程
# 若手动退出tom用户,root用户查看会变成“超时等待”状态,此时tcp协议只是以为网路不佳所以等待
[root@CentOS76 ~]# netstat -an | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN
tcp 0 36 192.168.137.128:22 192.168.137.1:64365 ESTABLISHED
tcp 0 0 192.168.137.128:22 192.168.137.1:52241 TIME_WAIT
tcp6 0 0 :::111 :::* LISTEN
# 下面还有很多就不演示了,主要是看ESTABLISHED、TIME_WAIT两个进程
# 注:若电脑配置很高,那可能会看不到该TIME_WAIT状态,不必在意,这里看到这个意思就行。
# 很快,tcp协议就对tom用户不抱什么希望了,于是便停止了tom用户的sshd进程
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN
tcp 0 36 192.168.137.128:22 192.168.137.1:64365 ESTABLISHED
tcp6 0 0 :::111 :::* LISTEN
【案例2】请查看服务名为sshd的服务的信息。
[root@CentOS76 ~]# netstat -anp | grep sshd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 9015/sshd
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 13232/sshd: root@pt
tcp 0 0 192.168.137.128:22 192.168.137.1:64365 ESTABLISHED 13232/sshd: root@pt
tcp6 0 0 :::22 :::* LISTEN 9015/sshd
tcp6 0 0 ::1:6011 :::* LISTEN 13232/sshd: root@pt
unix 2 [ ] DGRAM 143554 13232/sshd: root@pt
unix 3 [ ] STREAM CONNECTED 95215 9015/sshd
《鸟哥的Linux私房菜 基础学习篇 第四版》 ↩︎
《鸟哥的Linux私房菜 服务器架设篇 第三版》 ↩︎
《韩顺平_2021图解Linux全面升级》 ↩︎