14 Linux实操篇-进程管理(重点)

14 Linux实操篇-进程管理(重点)

文章目录

  • 14 Linux实操篇-进程管理(重点)
    • 14.1 进程的基本操作
      • 14.1.1 进程和程序
      • 14.1.2 父进程和子进程
      • 14.1.3 常见的Linux进程
      • 14.1.4 显示系统执行的进程-```ps```
      • 14.1.5 终止进程-```kill```/```killall```
      • 14.1.6 查看进程树-```pstree```
    • 14.2 后台进程管理指令
      • 14.2.1 查看服务名和运行级别
      • 14.2.2 早期版本指令-```service```
      • 14.2.3 早期版本指令-```chkconfig```
      • *14.2.4 当前常用指令-```systemctl```
      • 14.2.5 打开或关闭防火墙指定端口-```firewall```
    • 14.3 动态监控进程-```top```
    • 14.4 监控网络状态-```netstat```

  • 学习视频来自于B站【小白入门 通俗易懂】2021韩顺平 一周学会Linux。
  • 可能会用到的资料有如下所示,下载链接见文末:
  1. 《鸟哥的Linux私房菜 基础学习篇 第四版》1
  2. 《鸟哥的Linux私房菜 服务器架设篇 第三版》2
  3. 《韩顺平_2021图解Linux全面升级》3

14.1 进程的基本操作

14.1.1 进程和程序

内存
run
run
run
run
进程1
进程2
进程3
进程...
程序1
程序2
程序3
程序...
图14-1 “程序”和“进程”的关系

  本章首先来解释两个基本概念——“程序”和“进程”。如上图所示,“程序”就是一段代码,当运行起来时就会加载到内存中,于是就成为一个“进程”。也就是说,“程序”是静态的概念,“进程”是动态的概念。

  于是在Linux中,每个执行的程序都称为一个进程,并且每个进程都分配有一个ID号(PID, 进程号)。每个进程都可能以两种方式存在的——前台与后台:“前台进程”就是占有用户屏幕,可以进行交互操作的进程;“后台进程”则是实际在运行,但不会再屏幕显示的进程,通常使用后台方式执行,如用mysql操作数据库等。以下图所示的QQ软件举例,两台电脑上的QQ用户显然不能直接主机对主机通信,而是要首先将消息发送到QQ后台的服务器中进行转发,这种看不见的进程操作就是“后台进行”;而两台主机的用户都可以在各自的主机屏幕上发送/接收消息,这个显示在屏幕上支持交互操作的进程就是“前台进程”。值得一提的是,系统服务一般都是以“后台进程”的方式存在,而且都会常驻在系统中,直到关机才才结束。

不能直接发送消息
hello~
hello~
QQ用户1
(前台程序)
QQ用户2
(前台程序)
QQ服务器
(后台程序)
图14-2 “前台进程”和“后台进程”举例

14.1.2 父进程和子进程

创建
创建
创建
创建
创建
父进程1
systemd
子进程1197
sshd
子进程517
systemd-journald
子进程553
lvmetad -f
子进程...
子进程8005
sshd: root@pts/1
图14-3 父进程和子进程

  那既然“进程”就是执行的“程序”,由父程序可以调用子函数实现功能,显然进程也有“父进程”和“子进程”:若一个进程是多进程,也就是该进程可以创建“子进程”,那么这个进程就称为“父进程”。如上图所示,每次Linux系统启动时会调用systemd进程,在随后的过程中,其会创建sshdsystemd-journaldlvmetad -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小节再具体介绍。

14.1.3 常见的Linux进程

  本小节来介绍一个本章经常见到的Linux后台进程:sshd进程、network进程。

  1. sshd进程:SSHD(Secure Shell Daemon, 安全外壳守护进程)是在Linux系统上运行的一个守护进程,用于支持在不安全的网络环境下进行加密的远程登录。sshd进程决定了我们是否可以通过Xhsell远程登录到Linux上。
  2. network进程:是一个核心网络配置的进程,它包含了 Linux 网络设置中的所有业务代码,包括网络命令,网络状态监测,网络配置的重启等等。network决定了其他主机能否与该Linux系统ping通,显然也决定了Xhsell能否远程连接到Linux上。

更多介绍查看“Linux运维小知识之10个必须掌握的系统进程”。

14.1.4 显示系统执行的进程-ps

  前面三个小节介绍了操作系统中“进程”的概念。那该如何查看Linux系统中正在执行的进程以及它们执行的状况?答案是ps指令:

# 基本语法-ps
ps [选项]       # 查看正在执行的进程

# 常用选项-ps
-a  显示当前终端的所有进程信息
-u  以用户的格式显示进程信息
-x  显示后台进程运行的参数

-e  显示所有进程
-f  全格式

常用的ps组合选项有两种:ps -auxps -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 -auxps -ef还可以查看其父进程的进程号。

14.1.5 终止进程-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
# 当前终端也被直接关闭了。

14.1.6 查看进程树-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-}]

14.2 后台进程管理指令

  其实本节也成为“服务(service)管理指令”,但“服务”本质就是“后台进程”,所以为了名称的连贯性我将本节改名为“后台进程管理指令”。于是本节中所有的“后台进程”和“服务”等价。

14.2.1 查看服务名和运行级别

  自2014年7月7日正式发布CentOS7(RHEL7)以来,系统中的后台进程从原来的由systemV管理机制升级到了systemd。要想查看所有的后台进程,可以直接在终端输入setup-->选择“系统服务”回车,如下图:

14 Linux实操篇-进程管理(重点)_第1张图片 14 Linux实操篇-进程管理(重点)_第2张图片
图14-5 使用setup查看所有service管理的服务
  1. 使用tab键和↑↓方向键切换选项,Enter键确认选项。
  2. 有“星号”的服务会随着Linux系统的启动而自启,没有带“星号”的则需要手动启动。
  3. 要想去掉星号,需要将光标移动到相应的星号上,按空格键取消星号,再按一次添加星号。
  4. 可以看到SysV管理的服务只有两个,剩下的所有服务都在systemd中管理。

更多关于systemV和systemd的内容可以查看CSDN博客:

  • 2021-01的文章:“systemV和systemd的理解”
  • 2015-09的文章:“system V与systemd-”
开机
BIOS
/boot
systemd进程1
运行级别
启动运行级别对应的服务
图14-6 Linux开机流程

  如上图所示,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
表14-1 Linux系统的运行级别
级别 描述
0 停机状态。系统默认运行级别不能设置为0,否则系统不能正常启动。
1 单用户状态。此状态仅 root 用户可登录,用于系统维护,禁止远程登录,相当于 Windows 下的安全模式。
2【少见】 多用户状态(无NFS)。没有网络服务。
3【最常见】 完整的多用户状态(有NFS)。有网络服务,登录后进入控制台命令行模式。
4【少见】 系统未使用,保留一般不用,在一些特殊情况下可以用它来做一些事情。
例如在笔记本电脑的电池用尽时,可以切换到这个模式来做一些设置。
5【常见】 图形化模式,登陆后进入图形GUI模式或GNOME、KDE图形化界面,如X Window系统。
6 系统正常关闭并重启。默认运行级别不能设为6,否则不能正常启动,而是会一直开机重启开机重启。

14.2.2 早期版本指令-service

  “后台进程”通常都会监听某个端口,等待其它程序的请求,比如(mysqld, sshd防火墙等),因此“后台进程”又通常被称为“守护进程”,是Linux中非常重要的知识点。通常来说,“找端口”本质上就是找监听该端口的后台进程。关闭某个后台进程,相应的端口监听也就会停止。下图展示了后台进程监听端口的示意图:

Linux系统
监听
监听
连接
连接
mysql 服务/后台进程/守护进程
端口3306
sshd 服务/后台进程/守护进程
端口22
mysql客户端
Xshell客户端
图14-4 “进程”监听“端口”的示意图

  在早期版本的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 522 2020 functions
-rwxr-xr-x. 1 root root  4569 522 2020 netconsole   # 绿色高亮
-rwxr-xr-x. 1 root root  7928 522 2020 network      # 绿色高亮
-rw-r--r--. 1 root root  1160 102 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又可以连接了。

14.2.3 早期版本指令-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:关

*14.2.4 当前常用指令-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 101 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

713 19:50:00 CentOS76 systemd[1]: Starting firewalld - dynamic firewall daemon...
713 19:50:00 CentOS76 systemd[1]: Started firewalld - dynamic firewall daemon.
713 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)

713 19:50:00 CentOS76 systemd[1]: Starting firewalld - dynamic firewall daemon...
713 19:50:00 CentOS76 systemd[1]: Started firewalld - dynamic firewall daemon.
713 19:50:00 CentOS76 firewalld[857]: WARNING: AllowZoneDrifting is enabled. This is con...ow.
726 10:24:41 CentOS76 systemd[1]: Stopping firewalld - dynamic firewall daemon...
726 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

726 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...?).
726 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.
726 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...?).
726 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...?).
726 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.

细节讨论:

  1. 关闭或者启用防火墙后,立即生效。
  2. 这种方式只是临时生效,当重启系统后,还是回归以前对服务的设置。
  3. 如果希望设置某个服务自启动或关闭永久生效,要使用systemctl [enable|disable] 服务名

那如何只打开单个端口而不用关闭整个防火墙呢?下一小节介绍。

14.2.5 打开或关闭防火墙指定端口-firewall

Linux系统
监听
监听
监听
允许连接
允许连接
禁止连接
连接
连接
连接
防火墙
打开的端口
关闭的端口
mysql 服务/后台程序/守护进程
端口3306
sshd 服务/后台程序/守护进程
端口22
systemd 服务/后台程序/守护进程
端口111
mysql客户端
Xshell客户端
cmd客户端-Windows
图14-7 防火墙的作用演示
注:上述假设防火墙默认允许端口3306、22与外界连接,禁止端口111与外部连接

  首先来介绍一下什么是防火墙。如上图所示,防火墙的作用就相当于“护卫”,决定每一个访问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系统的防火墙非常强大,这里老韩只介绍了最简单的功能。

14.3 动态监控进程-top

  前面已经介绍了ps指令,可以查看系统所有的进程,甚至也可以查看每个进程占用CPU和内存的占用情况(ps -aux)。但是ps指令最大的缺点就是,ps的进程监控是静态的!那Linux下是否存在一种动态的监控指令,类似于Windows系统的“任务管理器-性能”窗口,可以实时的监控系统性能的变化呢?答案就是top指令。topps命令很相似,都用来显示正在执行的进程,但topps最大的不同之处,在于top指令是一种动态的监控,在执行一段时间后可以更新正在运行的的进程监控。

# 基本语法-top
top [选项]

# 选项说明-top
-d 秒数   指定top命令每隔几秒更新。默认是3秒
-i        使top不显示任何闲置或者僵死进程。
-p        通过指定监控进程ID来仅仅监控某个进程的状态。

# 交互操作-top(显示界面如何排序)
P   以CPU使用率排序,默认就是此项
M   以内存的使用率排序
N   以PID排序
q   退出top
14 Linux实操篇-进程管理(重点)_第3张图片
图14-8 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       # 终端输入即可

14.4 监控网络状态-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查看网络状态”。
Windows系统
外部地址 192.168.137.1:64365
外部地址 192.168.137.1:52241
Linux虚拟机
本地地址 192.168.137.128:22
监听
监听
监听
端口64365
Xshell进程-root用户
Xshell进程-tom用户
端口52241
端口22
sshd进程
图14-9 “本地地址”和“外部地址”示意图

下面展示两个应用案例:
【案例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   

  1. 《鸟哥的Linux私房菜 基础学习篇 第四版》 ↩︎

  2. 《鸟哥的Linux私房菜 服务器架设篇 第三版》 ↩︎

  3. 《韩顺平_2021图解Linux全面升级》 ↩︎

你可能感兴趣的:(#,Linux学习,linux,运维,服务器)