每日一讲(8.4-5)
一、描述 Linux 启动流程,从 BIOS 到用户登录。
Linux 启动流程,从 BIOS 到用户登录,大致流程为:
BIOS→Boot Loader→内核→initramfs→PID 1→多用户目标→登录。
1. BIOS/UEFI 阶段
- 按下电源键后,BIOS(或 UEFI)执行自检(POST),检测 CPU、内存、硬盘等硬件。
- 按设定的启动顺序,从硬盘、U盘等介质读取引导程序。
- UEFI 模式下读取 ESP 分区中的
EFI引导项;传统 BIOS 模式读取磁盘 MBR(主引导记录,第 0 扇区的前 446 字节)。
2. Boot Loader 阶段(GRUB2)
- 引导程序(常为 GRUB2)加载,读取配置文件
grub.cfg。 - 显示内核选择菜单(可配置超时),用户选择或按默认项。
- GRUB 将内核
vmlinuz和初始 RAM 盘initramfs(或initrd)加载进内存。
3. Kernel 阶段
- 内核解压并接管系统,初始化 CPU、内存管理、设备驱动。
- 挂载
initramfs(临时根文件系统),加载真正的磁盘驱动(如 SCSI/SATA/NVMe),随后切换到真实根文件系统(switch_root)。
4. init 阶段(systemd)
- 内核执行第一个用户态进程,通常是
/sbin/init(符号链接到 systemd),PID 为 1。 - systemd 读取目标(
default.target,通常是multi-user.target或graphical.target),并行启动各服务和单元(挂载、网络、守护进程)。
5. 登录阶段
- 串行/虚拟终端(tty)或图形登录管理器(如 GDM、SDDM)就绪。
- 用户输入账号密码,PAM 模块做认证,shell 或桌面环境启动,完成登录。
二、Linux 文件权限中的 suid, sgid, sticky bit 分别是什么?请举例说明。
**SUID / SGID / Sticky Bit **是 Linux 特殊权限位,在 rwx 之外控制程序的执行身份和目录的共享行为。
1. SUID(Set User ID,属主特殊位)
- 以文件属主身份执行,而不是执行者身份
- 表示符:
s出现在属主的x位置 - 最典型例子:
/usr/bin/passwd
-rwsr-xr-x 1 root root passwd
普通用户运行 passwd 时,临时以 root 身份修改 /etc/shadow(普通用户本无权限)。危险点:若给 shell 加 SUID,等于直接提权到 root。
2. SGID(Set Group ID,属组特殊位)
- 两种作用:文件上以属组身份执行;目录上新文件自动继承属组
- 表示符:
s出现在属组的x位置 - 示例:
-rwxr-sr-x 1 root staff team_tool
团队共享目录场景最常用:
drwxrws--- 2 root dev /srv/project
任何人往此目录新建文件,属组自动归为 dev,无需手动 chgrp。
3. Sticky Bit(粘滞位)
- 只对目录生效,限制文件删除权限
- 表示符:
t出现在其他人的x位置 - 经典例子:
/tmp
drwxrwxrwt root root /tmp
所有用户都能写,但只能删除自己拥有的文件,不能删别人的。防止共享目录里相互误删。
设置命令:
chmod u+s file # 加 SUID
chmod g+s dir # 加 SGID
chmod +t dir # 加 sticky
# 数字法:SUID=4, SGID=2, Sticky=1,如 chmod 4755
查看方法: 大写 S/T 表示对应执行位为空(如 rws → rwS),小写 s/t 表示执行位已设置。
安全提醒:SUID 提权风险最高,生产环境应定期用 find / -perm -4000 排查异常 SUID 文件。
三、软链接和硬链接的区别是什么?ln -s 和 ln 命令分别创建什么?
软链接和硬链接的区别,核心在于"指向文件本身"还是"指向数据块"。
硬链接(ln 创建)
它是多个文件名共享同一个 inode,也就是同一组数据块。每个硬链接都是平等的"真身",删掉其中一个,其他名字照样能读到数据。硬链接有两点限制:不能跨文件系统,也不能链接目录。用 ls -l 看时,第二列的数字就是链接数,普通文件的链接数是 1,每多一个硬链接就加一。
软链接(ln -s 创建)
它是一个独立的文件,文件内容存的是目标路径。它指向目标文件,一旦目标被删,软链接就变成"悬空"状态,虽然还在但已经失效。软链接没有硬链接的那些限制,可以跨文件系统,也可以链接目录。
总结
硬链接是同一个 inode 的多个名字,软链接是一个存路径的独立文件。判断方法很简单:ls -l 输出里,软链接的文件类型是 l,并且会显示箭头指向目标,例如 soft.txt -> old.txt;而硬链接看到的是和原文件相同的 inode 号。
实际使用中软链接更常见,比如系统里 /usr/bin/python3 指向 python3.12,各种配置文件也常用软链接,因为它直观、可跨盘、能指向目录。
四、如何查看一个进程打开的所有文件?如何查看一个端口被哪个进程占用?
两个经典问题,都是 Linux 运维面试高频题,我用命令直接说答案。
- 查看一个进程打开的所有文件
用 lsof 或 /proc 文件系统。
方法一:lsof(推荐)
lsof -p <PID>
-p指定进程号,列出该进程打开的所有文件描述符(普通文件、socket、管道、设备等)。
方法二:/proc 文件系统(无 lsof 时)
ls -l /proc/<PID>/fd/
- 每条记录是一个软链接,指向文件实际路径。比如
socket:[xxxxx]表示 socket,/path/to/file表示普通文件。
补充:
lsof -p <PID> | wc -l统计打开文件数- 想查进程名而不是 PID,
lsof -c <进程名>(注意是名字前缀匹配)
- 查看一个端口被哪个进程占用
方法一:ss(现代首选)
ss -tlnp | grep :<端口号>
-tTCP,-l监听,-n不解析服务名,-p显示进程。- 输出里会有
users:(("进程名",pid=xxx,...))。
方法二:netstat(老工具)
netstat -tlnp | grep :<端口号>
- 参数含义同上,很多系统需要
sudo才能看到-p的进程信息。
方法三:fuser(按端口反查)
fuser <端口号>/tcp
- 直接输出占用该端口的进程 PID,搭配
-v显示详细信息。
补充:
- 查 UDP 端口把
-t换成-u。 - 三个工具里
ss性能最好,是现代替代netstat的标准方案,底层读/proc/net/tcp。
五、cpu load 的含义是什么?如何解读 load average: 1.20, 0.85, 0.60?
CPU Load(负载)含义
Load 表示系统处于"可运行"和"不可中断睡眠"状态的进程数量之和,不是 CPU 使用率。它衡量的是系统整体"忙碌程度",包含等待 CPU 的进程、正在运行的进程,以及等待 I/O(磁盘、网络)的进程。
三个数值的含义
load average: 1.20, 0.85, 0.60 依次代表过去 1 分钟、5 分钟、15 分钟的平均负载。
关键看三个数之间的趋势和与** CPU 核数**的对比:
- 1 分钟 > 5 分钟 > 15 分钟 → 负载在上升(系统越来越忙)
- 1 分钟 < 5 分钟 < 15 分钟 → 负载在下降(系统趋于缓解)
- 三个数接近 → 负载平稳
判断是否过载,用负载值除以 CPU 核数(nproc 查看):
- 负载 ≈ 核数 → 刚好打满,CPU 处于饱和边缘
- 负载 < 核数 × 0.7 → 健康,有富余
- 负载 > 核数 × 1.0 → 已经排队,任务在等待
- 负载持续 > 核数 × 2.0 → 严重过载,响应变慢
假如机器是单核:
- 1.20 表示最近 1 分钟有约 1.2 个任务在排队,已经超过单核能力,有 0.2 个在等待
- 0.85、0.60 说明过去 5 分钟、15 分钟负载较低
- 整体趋势是负载在上升,需要关注
假如是四核机器:
- 1.20 远低于 4,说明负载很轻,完全健康,无需担心
注意点
- 单纯看 load 不够,通常需要结合 CPU 使用率。load 高但 CPU 空闲,往往是 I/O 瓶颈(进程在等磁盘)
- 云服务器显示的核数是 vCPU,不是物理核
- 短时峰值正常,要看 15 分钟均值和长期趋势做判断
六、free 命令输出中,buffers 和 cached 的区别?如何计算可用内存?
buffers 和 cached 的区别
两者都是内核把暂时不用的内存拿来当缓存,属于可回收内存,但用途不同:
- buffers(缓冲区):主要缓存块设备的原始元数据,比如文件系统的目录结构、inode、块映射等。读写块设备时用来暂存尚未落盘的块。
- cached(页缓存):缓存文件内容本身。读写过的文件页会留在内存,下次访问直接命中,不用再读磁盘。
简单说:buffers 管"文件在哪、结构是什么",cached 管"文件内容是什么"。
free 输出示例分析
total used free shared buff/cache available
Mem: 7.7G 2.1G 3.8G 12M 1.8G 5.3G
used= 2.1G(真正被进程占用的内存)buff/cache= 1.8G(缓冲+缓存,可随时回收)available= 5.3G(这才是真实的可用内存)
计算可用内存
关键点:free 里的 used 已经不包含 buff/cache,所以算可用内存不能简单用 free - total。
现代内核(Linux 3.14+)提供了现成的 available 字段,是最准确的可用内存,计算公式大致是:
available ≈ free + buff/cache 中可回收的部分(减去一部分不可回收的页缓存)
如果系统旧(没有 available),可手动近似:
可用内存 ≈ free + buffers + cached
但对 3.14+ 内核,不要自己算,直接用 available 列,因为内核还考虑了 SReclaimable(可回收 slab)和保留页,比手动 free + buff/cache 更精确。
实际经验:判断内存够不够、该不该告警,看 available,别看 free 那一列。free 只有几百兆但 buff/cache 很大时,内存通常还很健康,因为缓存能被立刻回收分配给进程。
七、描述 vmstat 1 5 输出中 r, b, swpd, si, so, us, sy, id, wa, st 字段的含义。
vmstat 1 5 表示每隔 1 秒采样一次,共采集 5 次。各字段含义如下:
进程(procs)
r:就绪队列长度,正在运行和等待 CPU 的进程数。长期大于 CPU 核数说明 CPU 是瓶颈。b:处于不可中断睡眠状态的进程数,通常是在等待 I/O,持续偏高说明磁盘或网络 I/O 有问题。
内存(memory)
swpd:已使用的交换空间大小,单位 KB。不为 0 不代表有问题,重点看它是否持续增长。si:每秒从交换区换入内存的数据量(KB/s)。持续较大说明物理内存不足。so:每秒从内存换出到交换区的数据量(KB/s)。和si同理。
CPU(cpu,百分比)
us:用户态 CPU 占比。高说明正在跑应用逻辑。sy:系统态(内核态)CPU 占比。长期偏高可能是频繁系统调用。id:空闲 CPU 占比。wa:等待 I/O 的 CPU 占比。偏高说明磁盘 I/O 是瓶颈,此时id往往也会被拉高。st:被虚拟机监控程序(hypervisor)偷走的 CPU 时间占比。只有虚拟机里才有意义,物理机恒为 0。
判断要点
- 看趋势不看病点:单次采样意义不大,要看多次采样的变化趋势。
r> CPU 核数 且us高 → CPU 瓶颈。wa稳定偏高、b高 → I/O 瓶颈。si/so持续大、swpd增长 → 内存不足,可能导致系统卡顿。
典型健康状态:id 高、wa 低、r 小于核数。
八、iostat -x 1 输出中,%util, await, svctm 分别代表什么?
iostat -x 1 是磁盘性能监控的常用命令。
%util
设备处理 I/O 请求的时间占比。数值接近 100% 说明磁盘长期处于忙碌状态,通常意味着接近性能瓶颈。注意:对 SSD 或 RAID,这个值可能虚高,不能简单当成"负载 100%"。
await
一次 I/O 请求从发出到完成消耗的平均等待时间(含排队等待和服务时间),单位毫秒。它反映用户体验到的延迟,包含了排队环节。
svctm
设备实际服务一次 I/O 请求花费的时间(不含排队),单位毫秒。它衡量磁盘本身的处理速度,跟请求队列长度无关。
判断逻辑
await大但svctm小 → 说明阻塞发生在排队环节,通常是请求过多或调度问题,而不是磁盘本身慢。- 两者都大 → 磁盘自身处理能力不足,考虑换盘或调整。
- 队列长度(
avgqu-sz)持续偏高 → 并发请求堆积,结合%util看是否真的饱和。
总结:svctm 看磁盘多快,await 看用户等多久,%util 看磁盘忙不忙。三者结合才能定位瓶颈在磁盘还是队列。