tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 各种MQ

  • Nginx

  • IdentityServer

  • Redis

  • Linux

    • Linux简介
    • Linux中一些常用命令
    • Linux中的文件复制与查找
    • 初识shell
    • shell-续与查看文件内容
    • 查看进程与shell
      • ps显示进程状态
        • 参数 -ef跟aux
        • 参数 -l
        • 参数 结合管道
      • top实时显示进程
        • 控制显示的列与排序
      • 结束进程kill
        • 信号与kill
        • 信号与进程通信
        • kill -9 pid
        • killall
      • 磁盘空间
        • 磁盘使用情况-df
        • du 指定空间使用情况
        • 挂载
        • windows中的挂载
        • mount 挂载
        • 挂载设备
        • 取消挂载
    • 查找数据与压缩
    • 再探shell
    • Linux系统中各个文件的作用
    • 【开发常用】Java开发必看
    • 【开发常用】软件安装利器
  • 中间件
  • Linux
EffectTang
2024-06-17
目录

查看进程与shell

# 查看进程与shell

上一章中简单介绍了存在硬盘上的文件,该如何查看以及相关操作。那本章便介绍下存在内存中的“文件”——进程,该何如查看以及相关的操作。

# ps显示进程状态

它来自英文单词process的缩写,其功能是显示当前系统的进程状态。使用ps命令可以查看到进程的所有信息,例如进程的号码、发起者、系统资源(处理器与内存)使用占比、运行状态等。它可谓是工作中最常用的命令之一了,因为不论是调试程序还是找bug都离不开它————只有了解程序状态后,我们才能知道怎么去修改。

找到问题所在,可比解决问题重要得多。

ps 命令默认(不加任何参数的情况下)显示当前终端会话中属于当前用户的进程。但是,通过不同的选项和技巧,你可以让它显示更多或不同的信息,包括系统中的所有进程。

 ps
 PID TTY          TIME CMD
 2553 pts/0    00:00:00 bash
 2893 pts/0    00:00:00 ps
26985 pts/0    00:00:00 sh
# 
1
2
3
4
5
6

ps,这是你刚刚执行的查看进程状态的命令所对应的进程。那bash跟sh是如何来的。

bash: 代表 Bourne Again SHell,是大多数Linux发行版默认的交互式shell。当你登录或者打开一个新的终端窗口时,系统会为你启动一个bash进程。这个bash进程是你与系统进行交互的基础,它负责解释你输入的命令并执行它们。因此,当你查看进程列表时,你总是能看到至少一个bash进程,因为正是它执行了你输入的 ps 命令。

sh:通常指的是 SHell,它是Unix/Linux环境中最早的shell之一,也是其他许多shell(包括bash)的祖先。在某些情境下,你可能会看到 sh 出现在进程列表中。这可能是因为某个脚本或程序是以 /bin/sh (通常是一个链接到系统默认shell的符号链接)来执行的,或者是由于某些命令或操作在后台启动了一个新的shell实例来处理特定任务。

那它能使用的参数有哪些呢?或者说常用的参数有哪些呢?实际上,ps能使用的参数比之前介绍的命令都要多得多,大多数Linux系统管理员都有自己的一组参数,他们会牢牢记住这些用来提取有用的进程信息的参数。下面就介绍几个个人认为用得比较多的参数或者参数组合。

# 参数 -ef跟aux

显示所有进程信息

ps -ef
# 显示系统中所有进程并用 完整格式
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0  2023 ?        00:02:44 /usr/lib/systemd/systemd --system --deserialize 21
root         2     0  0  2023 ?        00:00:01 [kthreadd]
root         4     2  0  2023 ?        00:00:00 [kworker/0:0H]
root         6     2  0  2023 ?        00:28:21 [ksoftirqd/0]
root         7     2  0  2023 ?        00:36:40 [migration/0]
root         8     2  0  2023 ?        00:00:00 [rcu_bh]
root         9     2  0  2023 ?        01:41:59 [rcu_sched]
.....
1
2
3
4
5
6
7
8
9
10
11
  • UID(用户ID):进程的属主。
  • PID(进程ID):进程的唯一标识符。
  • PPID(父进程ID):创建该进程的进程的ID。
  • C:进程的CPU利用率,以百分比表示(但这个值在 -f 输出中通常并不是CPU使用率,而是和进程优先级相关的一个值,在较新版本的ps中可能显示为 <defunct> 或空白)。
  • STIME:进程启动的时间。
  • TTY(终端类型):进程关联的终端设备,如果没有关联终端,则显示为 ? 或者空白。
  • TIME:进程至今为止所使用的CPU时间。
  • CMD:启动进程时使用的命令行。

除了-ef外,其实还有一组参数也可以展示所有进程信息,那就是aux

ps aux
# 采用BSD风格的输出格式,展示所有进程信息
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  43644  3832 ?        Ss    2023   2:44 /usr/lib/systemd/systemd --system --deserialize 21
root         2  0.0  0.0      0     0 ?        S     2023   0:01 [kthreadd]
root         4  0.0  0.0      0     0 ?        S<    2023   0:00 [kworker/0:0H]
root         6  0.0  0.0      0     0 ?        S     2023  28:21 [ksoftirqd/0]
......
1
2
3
4
5
6
7
8
  1. USER:运行此进程的用户名称。
  2. PID:进程的ID,这是进程在系统中的唯一标识。
  3. %CPU:进程占用的CPU时间百分比。
  4. %MEM:进程占用的物理内存百分比。
  5. VSZ:虚拟内存大小,即进程可以访问的地址空间总大小(包括交换空间)。
  6. RSS:常驻内存集大小,即进程在物理内存中实际占用的空间。
  7. TTY:进程是由哪个终端启动的,如果是在后台运行的守护进程,则通常显示为 ?。
  8. STAT:进程状态代码,常见的状态有:
  9. START:进程启动的时间,格式通常是HH:MM。
  10. TIME:进程累计CPU时间,格式为[[dd-]hh:]mm:ss。
  11. COMMAND:启动该进程的命令行,包括任何参数。

下面是常见的状态码(STAT):

  • R:运行中或可运行(在CPU运行队列中)。
  • S:睡眠中,等待某个事件发生。
  • D:不可中断的睡眠状态,通常因为I/O操作。
  • T:已停止(由信号或操作员)。
  • Z:僵尸进程,已经终止但其父进程尚未回收其资源。
  • W:无有效内存页的进程(罕见)。

-ef跟 aux都是用来查看系统中进程状态的命令,但它们遵循不同的风格和显示格式。

  • -ef: System V 风格的命令格式
  • aux: BSD 风格的命令格式。

根据个人需求来选择。

# 参数 -l

如果你不想看全部的进程信息,但又想看得更详细一些,你可以试下-l这个参数。

ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0  2553  2551  0  80   0 - 28887 do_wai pts/0    00:00:00 bash
0 R     0 17574  2553  0  80   0 - 38332 -      pts/0    00:00:00 ps
4 S     0 26985 26960  0  80   0 -   329 poll_s pts/0    00:00:00 sh
# 显示程序更多的状态信息 并用详细格式展示 (长格式展示)
1
2
3
4
5
6
  • F:内核分配给进程的系统标记。
  • S:进程的状态(O代表正在运行;S代表在休眠;R代表可运行,正等待运行;Z代表僵化,进程已结束但父进程已不存在;T代表停止)。
  • PRI:进程的优先级(越大的数字代表越低的优先级)。
  • NI:谦让度值用来参与决定优先级。
  • ADDR:进程的内存地址
  • SZ:假如进程被换出,所需交换空间的大致大小
  • WCHAN:进程休眠的内核函数地址

# 参数 结合管道

实际工作中,很少有人直接使用-ef或者aux,而是结合管道来寻找我们想要的程序,并查看它的状态——是否成功启动、异常以及是否需要重启或者其他操作。

ps -ef | grep 'your_program_name'
# 比如:寻找进程中 关于docker 相关的
ps -ef |grep docker
root     13640     1  0 6月02 ?       00:21:00 /usr/bin/dockerd
root     13645 13640  0 6月02 ?       00:40:55 docker-containerd --config /var/run/docker/containerd/containerd.toml
root     14064 12999  0 22:20 pts/0    00:00:00 grep --color=auto docker
1
2
3
4
5
6

列出所有进程信息后,通过管道 | 将这个输出传递给 grep 命令,grep 'your_program_name' 会在输出中搜索包含 your_program_name 字符串的行,从而帮助你找到与该程序相关的所有进程。当然,你也可以将-ef替换成aux。

下面是管道命令的简要介绍:

|(管道符号):它将前一个命令的输出作为后一个命令的输入。在这个场景中,它将 ps -ef 的输出作为 grep 的输入。

grep 是 "global regular expression print" 的缩写,用于搜索含有指定模式的行。这里,它在 ps -ef 的输出中搜索包含 your_program_name 的行,这个名称应该替换为你实际想要查找的程序名。

注意:由于 grep 自身也会作为一个进程出现在输出中,通常你会看到输出的最后一行是 grep your_program_name。为了排除这个干扰,可以使用如下命令:

ps -ef | grep 'your_program_name' | grep -v grep
1

grep -v grep 命令会过滤掉包含 grep 字符串的行,从而只显示真正匹配到的进程信息。

# top实时显示进程

ps,它只能显示某个特定时间点的信息。如果想要实时监控进程的状态变化,那么就需要使用top命令了。

top
# 使用后,会显示如下信息,且信息是变化的
top - 22:35:53 up 181 days, 23:37,  2 users,  load average: 0.23, 0.28, 0.26
Tasks: 103 total,   1 running, 102 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.1 us,  3.6 sy,  0.0 ni, 93.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1780812 total,   109472 free,   238436 used,  1432904 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  1354696 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                        
18101 root      10 -10  153880  23820   7100 S   5.6  1.3   5069:13 AliYunDunMonito                                                                                
    9 root      20   0       0      0      0 S   0.3  0.0 102:02.62 rcu_sched                                                                                      
11640 root      20   0  689588  11268   5320 S   0.3  0.6  93:34.44 aliyun-service                                                                                 
12997 root      20   0  157992   6528   4792 S   0.3  0.4   0:03.22 sshd                                                                                           
18090 root      10 -10  113296   7692   5460 S   0.3  0.4 395:58.37 AliYunDun  
# 如果要退出显示模式,可以通过 q 键,或者直接ctrl+c。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

在显示模式中,

输出的第一部分显示的是系统的概况:第一行显示了当前时间、系统的运行时间、登录的用户数以及系统的平均负载。 平均负载有3个值:最近1分钟的、最近5分钟的和最近15分钟的平均负载。值越大说明系统的负载越高。由于进程短期的突发性活动,出现最近1分钟的高负载值也很常见,但如果近15分钟内的平均负载都很高,就说明系统可能有问题。

Linux系统管理的要点在于定义究竟到什么程度才算是高负载。这个值取决于系统的硬件配置以及系统上通常运行的程序。对某个系统来说是高负载的值可能对另一系统来说就是正常值。通常,如果系统的负载值超过了2,就说明系统比较繁忙了。

第二行显示了进程概要信息——top命令的输出中将进程叫作任务(task):有多少进程处在运行、休眠、停止或是僵化状态(僵化状态是指进程完成了,但父进程没有响应)。

下一行显示了CPU的概要信息。top根据进程的属主(用户还是系统)和进程的状态(运行、空闲还是等待)将CPU利用率分成几类输出。

紧跟其后的两行说明了系统内存的状态。第一行说的是系统的物理内存:总共有多少内存,当前用了多少,还有多少空闲。后一行说的是同样的信息,不过是针对系统交换空间(如果分配了的话)的状态而言的。

最后一部分显示了当前运行中的进程的详细列表,有些列跟ps命令的输出类似。

# 控制显示的列与排序

默认情况下,top命令在启动时会按照%CPU值对进程排序。可以在top运行时使用多种交互命令重新排序。

而对于列名的展示,也是可控的。在top命令执行中,按f键允许你选择对输出进行排序的字段或者选择排序方式。

Fields Management for window 1:Def, whose current sort field is %CPU
   Navigate with Up/Dn, Right selects for move then <Enter> or Left commits,
   'd' or <Space> toggles display, 's' sets sort.  Use 'q' or <Esc> to end!

* PID     = Process Id             UID     = Effective User Id      TIME    = CPU Time               ENVIRON = Environment vars    
* USER    = Effective User Name    RUID    = Real User Id           SWAP    = Swapped Size (KiB)     vMj     = Major Faults delta  
* PR      = Priority               RUSER   = Real User Name         CODE    = Code Size (KiB)        vMn     = Minor Faults delta  
* NI      = Nice Value             SUID    = Saved User Id          DATA    = Data+Stack (KiB)       USED    = Res+Swap Size (KiB) 
* VIRT    = Virtual Image (KiB)    SUSER   = Saved User Name        nMaj    = Major Page Faults      nsIPC   = IPC namespace Inode 
* RES     = Resident Size (KiB)    GID     = Group Id               nMin    = Minor Page Faults      nsMNT   = MNT namespace Inode 
* SHR     = Shared Memory (KiB)    GROUP   = Group Name             nDRT    = Dirty Pages Count      nsNET   = NET namespace Inode 
* S       = Process Status         PGRP    = Process Group Id       WCHAN   = Sleeping in Function   nsPID   = PID namespace Inode 

1
2
3
4
5
6
7
8
9
10
11
12
13

确保在字段选择模式下,使用空格键切换列的显示状态后,仔细观察所选列名前是否有相应的符号变化(如 * 号出现或消失),然后再次按q或者ESC键返回显示界面。

用户在top命令的输出上有很大的控制权。用这个工具就能经常找出占用系统大部分资源的罪魁祸首。

# 结束进程kill

通过ps跟top,我们基本上能够实现对进程的监控了,但如果监控期间,发现了异常的进程(不断的消耗cpu资源且不释放等),我们还要学会去停止或者说终止它。

就像开车途中,如果车的某个部件出了问题,比如轮胎爆胎,或者方向盘失灵,我们都需要立刻停车进行修复,否则我们大概率会出意外,收到伤害。进程也如此,假如某个进程异常了,我们若不去处理它,那么我们的其他进程大概率会收到影响,最坏的结果就是直接宕机。

在linux中终止程序常用的命令就是kill pid(进程的id,通过ps或top命令可以查看)

kill 2577
# 2577 是某个进程的pid
1
2

使用该命令后,pid为2577这个命令,大概率会终止。之所以不是100%是因为,直接使用 kill PID(不带信号编号)时,默认发送的是 SIGTERM(信号15)。这是向进程发出的一个常规终止请求,意在允许进程优雅地关闭,执行必要的清理工作,比如关闭文件、释放资源等,然后退出。SIGTERM 是可捕获的,进程可以通过信号处理函数来决定如何响应这一信号,也就是说进程也可以不理会这个信号,不进行终止。

# 信号与kill

刚刚那段解释中,提到了信号编号,有些不理解。或者说,你可能不太理解为什么使用kill pid命令后,进程有不终止的情况。

kill pid
# 它其实等同于 kill -15 pid
# 它们都是 请求 进程 优雅地进行关闭
1
2
3

实际上,kill 命令在Linux中主要用于向指定进程发送信号,其最广为人知的用途确实是终止进程,但这并不是它的唯一功能。实际上,kill 命令能够发送多种不同类型的信号,每种信号都会使接收进程执行不同的操作。除了终止进程之外,它还可以用于以下目的:

  1. 暂停进程:发送 SIGSTOP(信号19)可以暂停一个进程的执行。进程会停止运行,直到接收到继续执行的信号。
  2. 恢复进程:发送 SIGCONT(信号18)可以恢复一个被暂停的进程的执行。
  3. 重置终端:发送 SIGHUP(信号1)传统上用于通知进程终端连接已经断开,很多服务进程会因此重新加载配置文件或重启。
  4. 请求进程进行清理工作并退出:发送 SIGTERM(信号15)是一个温和的请求,指示进程应该清理资源并正常退出。这是默认的终止信号。进程可以自由决定如何响应,包括忽略信号(即不执行终止)、执行清理操作后退出或立即退出。如果进程正在进行某些关键操作或因编程不当未处理该信号,它可能不会立即终止。
  5. 强制终止进程:发送 SIGKILL(信号9)是强制进程立即终止的最强信号,进程无法忽略这个信号,也无法执行任何清理操作,直接被内核终结。

# 信号与进程通信

至于信号,它则是不同进程之间进行通信的一种手段。

不同的进程之间是需要通信的,主要是为了以下目的:

  1. 资源共享:进程间通信允许一个进程访问另一个进程的数据或资源,实现了系统资源的有效共享。例如,多个进程可以共享同一块内存区域来交换数据,避免了数据复制的开销。
  2. 任务协调与同步:在多进程环境中,不同进程可能需要协同工作来完成复杂的任务。通过进程间通信,可以实现进程间的同步(如互斥访问共享资源)、互斥(防止多个进程同时修改同一资源导致数据混乱)和协作(如生产者-消费者模型)。
  3. 数据传递:进程间通信是传递控制信息或数据的基本手段。无论是简单的消息通知还是大量数据的交换,合适的通信机制都能保证数据准确无误地从一个进程传递到另一个进程。
  4. 模块化和解耦:通过进程间通信,可以让程序的不同部分(作为独立的进程)专注于自己的功能,而不需要了解其他部分的内部细节。这样提高了系统的模块化程度,降低了模块间的耦合度,便于维护和扩展。
  5. 容错与可靠性:在一些设计中,进程间的监控与通信机制可以用来检测进程故障并采取恢复措施,提高了系统的整体稳定性和可靠性。

所以说,kill pid,其实就进程间的通信,等于一个进程告诉另一个进程,你该终止了。

进程间的通信不只——信号,这一种方式,包括但不限于管道、消息队列、共享内存、信号量、信号、套接字和内存映射等。每种方法都有其特点和适用场景。这些多样化的通信手段使得开发者可以根据实际需求,如数据传输量、实时性要求、同步需求或是网络通信能力等,灵活选择最合适的通信方式来设计和实现多进程间的协作。

# kill -9 pid

使用 kill -9 PID 时,发送给进程的是 SIGKILL(信号9)信号。这是一个立即终止进程的信号,它不能被进程捕获、阻塞或忽略,因此进程没有机会执行任何清理工作。操作系统会直接终止进程,无论进程当前在做什么。SIGKILL 相当于是对进程下达的“终极命令”,进程会在执行的那一刻被强行停止。

优势:

  • 确保进程无条件终止,适用于那些不再响应其他信号的“僵尸”进程。
  • 快速有效,无需进程的配合。
  • 在需要立即停止服务或进程时非常有用,特别是在紧急情况下。

不过,它应当作为最后的选择,因为它可能导致数据丢失或资源泄漏,因为它要求进程立即终止,不管当前任务是否完成。

# killall

killall命令非常强大,它支持通过进程名而不是PID来结束进程。killall命令也支持通配符,这在系统因负载过大而变得很慢时很有用。

killall http*
1

注意:以root用户身份登录系统时,使用killall命令要特别小心,因为很容易就会误用通配符而结束了重要的系统进程。这可能会破坏文件系统。

# 磁盘空间

# 磁盘使用情况-df

在使用电脑工作时,除了进程,是我们关注的一大重点之外,还有其他许多参数我们也要重点关注,其中之一就是磁盘空间,该电脑目前的使用情况如何,我们还可以用多少。

df是一个用来显示系统上磁盘空间的使用量情况的命令。df命令显示的磁盘使用量情况含可用、已用及使用率等信息,默认单位为KB

df
文件系统          1K-块    已用     可用 已用% 挂载点
devtmpfs         879296       0   879296    0% /dev
tmpfs            890404       0   890404    0% /dev/shm
tmpfs            890404     600   889804    1% /run
tmpfs            890404       0   890404    0% /sys/fs/cgroup
/dev/vda3      40959536 9447348 29620988   25% /
/dev/vda2        195372   11480   183892    6% /boot/efi
overlay        40959536 9447348 29620988   25% /var/lib/docker/overlay2/317ea72d2c2c2f7180169b39c2a9f716dac470967fe82eb92f32e9b149922e15/merged
shm               65536       0    65536    0% /var/lib/docker/containers/8ca670701cc28a4da8b1c2a63f021f947939d45c29f937e9d4acfc25a7bae5a3/mounts/shm
tmpfs            178084       0   178084    0% /run/user/0

1
2
3
4
5
6
7
8
9
10
11
12

它的默认单位有点小,如果想换成大一点的M或者G,可以考虑使用参数-h

df -h
文件系统        容量  已用  可用 已用% 挂载点
devtmpfs        859M     0  859M    0% /dev
tmpfs           870M     0  870M    0% /dev/shm
tmpfs           870M  600K  869M    1% /run
tmpfs           870M     0  870M    0% /sys/fs/cgroup
/dev/vda3        40G  9.1G   29G   25% /
/dev/vda2       191M   12M  180M    6% /boot/efi
# -h 按照用户易读的方式展示
1
2
3
4
5
6
7
8
9

# du 指定空间使用情况

df是整个电脑中,各个磁盘的使用情况,并不能看到文件夹中不同的文件夹所占大小。实现这一目标,所要使用的命令是du。它的名字来源于“disk usage”。du 命令可以递归地遍历目录树并显示指定目录及其包含的文件和子目录的磁盘使用情况。默认情况下,du命令会显示当前目录下所有的文件、目录和子目录的磁盘使用情况。

它很适合用来检测某个目录下是否有大文件存在。

du
4       ./.ssh
4       ./.pki/nssdb
8       ./.pki
8       ./.cache/pip/http/f/e/d/0/e
12      ./.cache/pip/http/f/e/d/0
16      ./.cache/pip/http/f/e/d
20      ./.cache/pip/http/f/e
24      ./.cache/pip/http/f
36      ./.cache/pip/http/b/b/8/7/6
40      ./.cache/pip/http/b/b/8/7
44      ./.cache/pip/http/b/b/8
48      ./.cache/pip/http/b/b
52      ./.cache/pip/http/b
80      ./.cache/pip/http
88      ./.cache/pip
92      ./.cache
8       ./.pip
164     .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

第一列是磁盘使用量,第二列是对应的文件或目录路径。

当然,它也有很多参数可选,下面介绍一些常用的:

# du 参数名 文件夹 
# 以上是它的 语法格式
du -ch /etc
4.0K    ./.ssh
4.0K    ./.pki/nssdb
8.0K    ./.pki
8.0K    ./.cache/pip/http/f/e/d/0/e
12K     ./.cache/pip/http/f/e/d/0
16K     ./.cache/pip/http/f/e/d
20K     ./.cache/pip/http/f/e
24K     ./.cache/pip/http/f
# ..... 省略部分列
# -h 按照用户易读的方式展示
# -c 显示所有已列出文件总的大小
1
2
3
4
5
6
7
8
9
10
11
12
13
14

-m,以MB为单位显示文件大小。更多参数,欢迎大家自行查阅资料。

# 挂载

磁盘空间越大你能安装的程序的就越多,或者能存放的资料就越多。但,如果磁盘空间不大,你还可以使用移动存储媒体(比如:U盘,移动硬盘之类的)去存储。

但在Linux中,如果要使用新的存储媒体,需要把它放到虚拟目录下,这项工作称为挂载,在Linux中就是通过mount指令来实现挂载。挂载主要是确保了用户和程序能够通过一个已知的目录路径来透明地访问存储设备上的文件和数据。简单的说,就是通过一个目录来访问设备中的资料。

其实只要是文件系统,就会用到挂载命令,并非只是移动存储设备才会用到。最直接的证明就是使用mount命令后,即使你电脑没插入任何u盘之类的存储设备,你也能看到许多输出。

挂载它主要做了以下几件事:

  1. 识别文件系统:检测存储设备上的文件系统类型。
  2. 选择挂载点:在系统目录树中选定一个位置作为访问新文件系统的入口。
  3. 加载驱动:必要时,加载对应文件系统的驱动程序。
  4. 链接文件系统:将文件系统的根目录与挂载点目录相连,整合进系统目录结构。
  5. 配置权限与选项:根据指令设置访问权限(如读写、只读)和其他挂载参数。
  6. 系统记录更新:更新内部记录,如挂载表,确保系统能追踪和管理挂载状态。

# windows中的挂载

在windows系统中,我们使用移动设备(U盘之类),直接插入电脑,就能使用了,似乎根本没做什么挂载操作。但,实际上,Windows操作系统对于物理存储设备如U盘也进行了挂载操作,只是这个过程对用户而言通常是透明的,不像Linux中用户可能需要手动执行挂载命令。在Windows中,当U盘或其他可移动存储设备插入时,系统会自动执行一些系列操作,来完成挂载该动作。对于我们来说,就是看到电脑新增了一个盘符。

# mount 挂载

默认情况下,mount命令会输出当前系统上挂载的设备列表。

mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
devtmpfs on /dev type devtmpfs (rw,nosuid,size=879296k,nr_inodes=219824,mode=755)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,nodev,mode=755)
# 省略部分输出
1
2
3
4
5
6
7
8
9

输出的信息每一行描述了一个已挂载的文件系统及其相关信息。这些信息通常包括以下几部分,每部分对应的意义如下:

  1. 文件系统类型(如ext4, tmpfs, nfs等):表示挂载的文件系统的类型。
  2. 挂载点(如/, /home, /mnt/mydrive等):文件系统在系统目录树中的具体挂载位置。
  3. 设备名称或源(如/dev/sda1, none, 192.168.1.100:/volume等):表示文件系统所在的物理设备或网络资源的位置。
  4. 选项(如rw, ro, noexec, async等):挂载时使用的特定选项,控制访问权限、读写能力、同步或异步IO等。

下面对其中一行进行一个简单的解析:

sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
1
  • sysfs: 表示文件系统类型为sysfs。
  • on /sys: 指明sysfs文件系统被挂载到了/sys目录下。这意味着你可以在/sys目录中查看和修改与内核相关的信息和设置,如硬件设备的状态、驱动参数等。
  • type sysfs: 重复说明了文件系统的类型,这里是sysfs。
  • (rw,nosuid,nodev,noexec,relatime): 列出了挂载该文件系统时采用的选项:
    • rw: 表示文件系统被挂载为可读写的。
    • nosuid: 禁止在此文件系统上执行Set-UID和Set-GID位的程序,增加了安全性。
    • nodev: 禁止在此文件系统上创建设备文件,因为sysfs本身是用来展示设备信息的,不需要创建新设备。
    • noexec: 禁止在这个文件系统上执行任何程序或脚本,进一步增强了安全性,因为sysfs主要是用来查看系统状态而非执行代码。
    • relatime: 更新文件或目录的访问时间戳只有在文件或目录的内容被访问时才进行,相比atime更新策略,这样可以减少磁盘I/O,提高性能。

# 挂载设备

上面只展示了挂载的信息,如果要进行手动挂载的话,则需要进行如下操作:

mount -t type device directory
# 语法格式:mount 参数 设备名 目录名
# eg.
mount -t vfat /dev/sdb1 /media/disk
# 手动将U盘/dev/sdb1 挂载到 /media/disk
# 再比如
mount -t vfat /dev/sdb1 /mnt/usb
mount -t ntfs-3g /dev/sdc1 /mnt/hdd
1
2
3
4
5
6
7
8

其中,-t参数的作用:挂载指定文件类型的设备分区。更多的参数这里就不展开介绍了。

现如今,挂载移动存储设备时,通常不需要显式指定设备的类型参数,因为系统能够自动探测大多数常见设备的文件系统类型。但指定文件类型依旧有效。

你可能会想手动指定是否会比自定指定快一些。实际上,并不会,挂载操作的速度主要由硬件速度、文件系统复杂度、系统负载等因素决定。

这里值得一提的是,要手动在虚拟目录中挂载设备,需要以root用户身份登录,或是以root用户身份运行sudo命令。

# 取消挂载

如果不使用u盘等移动存储设备了,我们还需要取消挂载,之后再拔掉设备。为什么直接拔掉不可以呢?主要原因有以下几个:

  1. 数据丢失或损坏:如果移动设备正在被读取或写入数据,直接拔除可能会导致当前操作中断,从而引起文件系统的不一致性,造成数据丢失或损坏。
  2. 设备损坏:虽然USB接口设计有一定程度的热插拔能力,但频繁或不当的直接拔除操作可能增加设备端口或设备本身的物理损坏风险。
  3. 挂载点残留:在Linux系统中,直接拔除可能会导致挂载点变为“忙碌”状态,未来再次挂载该设备时可能会遇到问题,需要手动清理或修复挂载点。

取消挂载的命令是umount,它的用法也很简单。

# 语法 umount 参数 设备或目录名
umount -v /dev/sdb
# 卸载指定文件系统 并显示过程
1
2
3

如果有任何程序正在使用设备上的文件,系统就不会允许你卸载它:

umount /dev/sdb
umount: /dev/sdb: device is busy
1
2

如果在卸载设备时,系统提示设备繁忙,无法卸载设备,通常是有进程还在访问该设备或使用该设备上的文件。这时可用lsof 命令获得使用它的进程信息,然后在应用中停止使用该设备或停止该进程。lsof命令的用法很简单:

lsof /path/device/node
#
lsof /path/to/mount/point
1
2
3
上次更新: 2025/04/23, 16:23:16
shell-续与查看文件内容
查找数据与压缩

← shell-续与查看文件内容 查找数据与压缩→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式