Appearance
树形目录结构
bash
/
├── bin -> usr/bin # 二进制可执行文件(软链接到/usr/bin)
├── boot # 内核文件与启动引导文件
├── dev # 设备文件(如磁盘、终端等)
├── etc # 系统全局配置文件
| ├── hosts # 主机名映射文件
│ ├── sysconfig/network-scripts/ # 系统网卡配置文件所在路径
│ └── systemd/system/ # 系统systemd服务文件存储.service
├── home # 普通用户家目录的宿主目录(每个用户独立子目录))
├── lib -> usr/lib # 基础共享库(软链接到/usr/lib)
├── media # 可移动设备挂载点(如U盘、光盘)
├── mnt # 临时手动挂载目录
├── opt # 第三方软件安装目录
├── proc # 内核与进程的虚拟文件系统(临时存放内存的目录)
├── root # root用户的家目录
├── run # 运行时数据(如PID文件)
├── sbin -> usr/sbin # 管理员用户的二进制命令,系统管理命令(软链接到/usr/sbin)
├── srv # 服务相关数据(如Web、FTP数据)
├── sys # 系统硬件信息的虚拟文件系统
├── tmp # 临时文件(所有用户可写)
├── usr # 用户程序与资源(二级层级结构)
│ ├── bin # 用户命令
│ ├── lib # 库文件
│ ├── local # 本地安装的软件
| | ├── bin/ # 用户可执行文件(如 nginx、python3)
| | ├── lib/ # 库文件
| | ├── include/ # 头文件(C/C++开发)
| | ├── share/ # 文档、数据等
| | └── src/ # 可选:存放源码
│ ├── sbin # 系统管理命令
│ └── share # 架构无关数据(如文档、字体)
└── var # 可变文件和临时文件(日志;缓存;临时存储)
├── log # 系统日志
├── cache # 应用程序缓存
└── lib # 程序状态数据
/opt和/usr/local/关键区别
特性 | /opt | /usr/local |
---|---|---|
用途 | 第三方独立软件包 | 本地编译/手动安装的软件 |
结构 | 每个软件独占子目录 | 仿照 /usr 的层级结构 |
管理方式 | 由软件供应商提供 | 通常由管理员手动编译安装 |
典型内容 | 商业软件、预编译二进制 | 开源软件、自定义程序 |
卸载便利性 | 直接删除对应目录即可 | 需手动清理分散的文件 |
如何选择
- 使用
/opt
:- 软件是独立的、预编译的,且希望所有文件集中存放(如
/opt/myapp/bin
)。 - 软件由供应商提供安装脚本(如
./install.sh
)。
- 软件是独立的、预编译的,且希望所有文件集中存放(如
- 使用
/usr/local
:- 从源码编译安装,且需要集成到系统路径(如
/usr/local/bin
已在$PATH
中)。 - 软件需要标准的 Unix 文件布局(如
bin
、lib
分离)。
- 从源码编译安装,且需要集成到系统路径(如
注意事项
PATH 环境变量
/usr/local/bin
通常默认在 $PATH
中,而 /opt/<package>/bin
可能需要手动添加。
bash
export PATH="/opt/myapp/bin:$PATH"
权限管理
/opt
和 /usr/local
通常需要 root
权限写入,但软件运行时可用普通用户权限。
冲突避免
避免将同一个软件同时安装在 /opt
和 /usr/local
中。
/dev特殊设备文件说明
/dev/null
- 写入的数据会被丢弃,读取时返回 EOF(文件结束)。常用于屏蔽命令输出。
- 示例:
command > /dev/null 2>&1
/dev/zero
- 提供无限的空字符(
\0
),常用于初始化文件或内存。 - 示例:
dd if=/dev/zero of=testfile bs=1M count=100
- 提供无限的空字符(
/dev/random
和/dev/urandom
- 生成随机数据:
/dev/random
阻塞直到收集足够熵,/dev/urandom
非阻塞但安全性稍低。 - 示例:生成随机密码:
head -c 16 /dev/urandom | base64
- 生成随机数据:
/dev/stdin
、/dev/stdout
、/dev/stderr
- 分别对应标准输入、输出、错误流,常用于重定向。
/dev/tty
- 表示当前终端设备,可用于强制输出到终端(如脚本中交互提示)。
/dev/loopX
- 虚拟设备,用于挂载镜像文件(如 ISO)到文件系统。
/dev/sdX
或/dev/nvmeXnY
- 物理磁盘设备(如
/dev/sda
为第一块 SATA 硬盘)。
- 物理磁盘设备(如
/etc关键配置文件解析
- /etc/inittab:系统初始化配置文件
/etc/passwd
:用户账户信息(不含密码,密码在/etc/shadow
中)。/etc/shadow
:存储用户加密密码,仅 root 可读。/etc/group
:用户组定义信息。/etc/fstab
:定义开机自动挂载的分区和设备。/etc/hosts
:本地主机名与 IP 映射,可绕过 DNS 解析。/etc/resolv.conf
:DNS 服务器配置。/etc/ssh/sshd_config
:SSH 服务端配置(如端口、密钥登录等)。/etc/crontab
和/etc/cron.d/
:系统级定时任务配置。/etc/sudoers
:定义用户 sudo 权限(需用visudo
编辑)。/etc/os-release
:系统发行版信息(如版本号、名称)。/etc/null
:黑洞文件/etc/zero
:零时文件- /etc/profile:全局环境变量文件
- /etc/securetty:登录终端配置文件
- /etc/systemd/system/:系统systemd服务文件
.service
存储 - /etc/sysconfig/network-scripts/:网卡文件存储目录
/var可变文件和临时文件
- /var/spool/cron/<应户名>:定时任务存放位置
- /var/spool/mail/<用户名>:系统邮件的保存位置
- /var/spool/postfix/maildrop/:系统邮件产生的小文件保存位置(邮件服务
postfix
关闭时产生)
/var用户程序与资源
- /usr/bin:存放非基础系统命令(与
/bin
的区别是不包含启动/修复必需命令) - /usr/sbin:系统管理员专用命令
- /usr/lib:程序库文件存储
- /usr/include:开发头文件
- /usr/share:项目文档手册存储
- /usr/local:本地编译安装软件位置
- /usr/src:内核源码和驱动开发文件
Linux日志体系详解
/var/log/syslog
或/var/log/messages
- 系统全局日志(取决于发行版)。
/var/log/auth.log
- 认证相关日志(如 SSH 登录记录)。
/var/log/kern.log
- 内核日志(硬件、驱动问题排查)。
/var/log/apt/
或/var/log/dnf.log
- 包管理器日志(安装/更新记录)。
运行时和内核文件
/proc/
目录- 虚拟文件系统,实时反映内核和进程状态:
/proc/cpuinfo
:CPU 信息。/proc/meminfo
:内存使用情况。/proc/net/
:网络状态(如/proc/net/tcp
)。
- 虚拟文件系统,实时反映内核和进程状态:
/sys/
目录- 另一个虚拟文件系统,管理设备、驱动和内核参数。
inode 与 block
文件储存在硬盘上,硬盘的最小储存单位叫“扇区”(sector),每个扇区储存 512 字节。 操作系统读取硬盘的时候,不会一个个扇区的读取,这样效率太低,而是一次性连续读 取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取 的最小单位。“块”的大小,最常见的是4KB,即连续八个 sector 组成一个 block。 文件数据存储在“块”中,那么还必须找到一个地方存储文件的元信息,比如文件的创 建者、文件的创建时间,文件的大小等等。这种储存文件元信息的区域叫做inode,中文译 名为“索引节点”,也叫 i 节点。
NOTE
一个文件必须占用一个 inode,但至少占用一个block
inode文件源信息
索引节点(inode)是文件系统的元数据仓库,每个文件/目录对应唯一inode。
文件的字节数、拥有者的 UID、GID、文件的读写执行权限、时间戳等,但不包含文件 名。文件名是储存在目录的目录项中。
c
struct inode {
uid_t owner; // 所属用户
gid_t group; // 所属组
mode_t permissions; // 权限模式
loff_t size; // 文件大小
time_t atime; // 访问时间
time_t mtime; // 修改时间
time_t ctime; // 状态变更时间
blkcnt_t blocks; // 占用块数
// 12个直接指针 + 3级间接指针
}
查看文件的 inode
bash
[root@localhost ~]# stat 1.txt
文件:1.txt
大小:0 块:0 IO 块大小:4096 普通空文件
设备:253,0 Inode: 131079 硬链接:1
权限:(0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
上下文:unconfined_u:object_r:admin_home_t:s0
访问时间:2025-05-10 10:21:51.309179685 +0800
修改时间:2025-05-10 10:21:51.309179685 +0800
变更时间:2025-05-10 10:21:51.309179685 +0800
创建时间:2025-05-10 10:21:51.309179685 +0800
Atime、Mtime、Ctime 详解
英文别称 | 中文翻译 | 何时修改 | 查看命令 |
---|---|---|---|
Access | Atime (访问时间) | 文件被读取或写入时 | ls -lu |
Modify | Mtime (修改时间) | 文件内容被写入或修改时 | ls -l |
Change | Ctime (改变时间) | 修改文件名、写入内容、更改权限、创建硬链接时 | ls -lc |
- Atime 更新场景:
- 使用
cat
查看文件 - 程序读取文件内容
grep
搜索文件
- 使用
- Mtime 更新场景:
vim
保存文件echo >>
追加内容- 文件被截断 (
truncate
)
- Ctime 更新场景:
chmod
修改权限chown
修改所有者mv
重命名文件- 创建硬链接
修改时间戳
在Linux中,可以使用 touch 命令来修改文件的时间戳。 touch 命令可以同时修改文件的访问时间(atime)、修改时间(mtime)和状态改变时间(ctime)。
以下是一些常用的 touch 命令选项:
-a
: 只修改访问时间-m
: 只修改修改时间-t
: 指定具体的时间戳,格式为 [[CC]YY]MMDDhhmm[.ss]
bash
# 修改访问时间和修改时间
touch -t 200003101030.00 text.txt
# 只修改访问时间
touch -a -t 200103101030.00 text.txt
# 只修改修改时间
touch -m -t 200203101030.00 text.txt
目录文件的结构
每个 inode 都有一个号码,操作系统用 inode 号码来识别不同的文件 Linux 系统内部不使用文件名,而使用 inode 号码来识别文件。对于系统来说,文件名 只是 inode 号码便于识别的别称。
black
block是基本存储单位
存储规则:
默认块大小:4KB(可通过
dumpe2fs
查看)大文件分配策略:
mermaidgraph LR 直接块-->|≤48KB|12个直接指针 间接块-->|≤4MB|一级间接指针 双间接块-->|≤4GB|二级间接指针 三间接块-->|≤4TB|三级间接指针
inode 一般为 128 字节或 256 字节,每个 inode 中都记录着文件所在的 block 号, 每条记录着block 号的信息占用 4 字节。inode 中关于 block 号的记录一共包含有 12 个 直接、1 个间接、1 个双间接和 1 个三间接。
12 个直接连接
共占用 48 字节磁盘空间,包含着 12 个直接指向 block号的信息,若此文件系统默认的 block 大小为 4KB,则仅仅可以指向 12*4=48KB 大小的文件内容,然而我们的文件若较大时,则需要使用到更多的 block,肯定要多于 12 个 block,进而 有间接、双间接和三间接。
一个间接
inode 中所记录这 4 字节的内容,所指向一个 block,这个 block 中存放的不是真是的文件内容,而是真实文件所存放位置的 block 号信息,若每个 block大小为 4KB,那么可以存放 1024个 block 号信息,1 个间接可以存放的文件大小为:1024*4=4096KB 。
双间接
可以存放更大的文件内容,即在间接的基础上再进行间接,若此时 block 大小为默认的4KB,则 1 个双间接可以存放的文件内容大小为:102410244=4096MB。
三间接
即在双间接的基础上在进行间接,若此时 block 大小为默认的 4KB,则 1 个 三间接可以存放的文件内容大小为:102410241024*4=4096GB。也就是说,在一个 block 大小默认为 4KB 的文件系统中,一个文件最大存储可以达 到 48KB+4096KB+4096MB+4096GB,约为 4100G
查看文件的 inode 号码
bash
ls -i 文件名
stat 文件名
mermaid
graph TD
subgraph 左侧
A[文件名]
B[元信息]
C[数据]
end
subgraph 右侧
D[目录项]
E[inode]
F[block]
end
A --> D
B --> E
C --> F
对应关系:
- 文件名 ↔ 目录项(存储文件名到inode的映射)
- 元信息 ↔ inode(存储权限/时间戳等)
- 数据 ↔ block(实际存储文件内容)
查看文件系统的 inode 与 block
bash
# 文件系统已挂载时查询,查询 inode 总数与已用数量
df -i 设备名
# 需要 ext4 系统类型(文件系统无需挂载)
dumpe2fs -h 设备名
# 需要 ext4 系统类型(文件系统无需挂载)
tune2fs -l 设备名
设置文件系统inode和block大小
bash
mkfs.ext4 -N inode 数 -b 块大小(单位字节) 设备名
解决 inode 耗尽导致的
- 删除不使用的文件
- 将文件备份,重新格式化此文件系统,指定较多的 inode 个数
Linux删除文件本质
在Linux系统中,删除文件的本质并非立即擦除磁盘数据,而是没有目录项(硬链接)指向该inode和没有进程正在打开该文件,此时系统才会释放inode编号并且标记数据块为可重用。
核心概念
- Inode(索引节点):存储文件的元数据(如权限、大小、数据块位置等),但不包含文件名或内容。
- 硬链接(i_nlink):记录指向该文件的目录项数量。当i_nlink=0且无进程引用时,文件才会被真正删除。
- 进程引用(i_count):若文件被进程打开(如tail -f),即使i_nlink=0,数据仍保留至进程关闭。
删除流程
- 步骤1:执行rm命令后,系统减少文件的i_nlink值。若i_nlink>0(存在其他硬链接),仅删除当前目录项。
- 步骤2:检查i_count值。若i_count>0(文件被进程占用),延迟释放数据块和Inode。
- 步骤3:当i_nlink=0且i_count=0时,系统标记Inode和数据块为可重用,空间被回收
恢复可能性
- 若文件刚被删除且磁盘未被覆盖,可通过工具扫描残留数据块恢复
- 若文件仍被进程占用(
i_count>0
),可通过lsof
查找进程并恢复文件
Linux 文件系统链接
在 Linux 中,链接(Link)分为**硬链接(Hard Link)和符号链接(Symbolic Link,又称软链接)**两种类型。它们的主要区别在于存储方式、跨文件系统支持以及删除原文件的影响。
硬链接
特点
- 直接指向 inode,与原始文件共享相同的 inode 和数据块。
- 不能跨文件系统(因为 inode 只在同一个文件系统内有效)。
- 删除原文件不影响硬链接(只有当所有硬链接都被删除时,数据才会真正释放)。
- 目录不能创建硬链接(防止循环引用问题)。
目录特殊性:
- 每个目录至少包含2个硬链接:
- 目录自身的链接(
.
) - 父目录的链接(
..
)
- 目录自身的链接(
- 每增加一个子目录,父目录链接数+1
- 目录硬链接只统计下一级子目录的数,不统计文件和子子级以下的目录数
创建硬链接
bash
ln 源文件 硬链接名
示例
bash
echo "Hello" > original.txt
ln original.txt hardlink.txt
ls -li # 查看 inode(硬链接和原文件相同)
符号链接(软链接)
特点
- 存储的是目标文件的路径,而不是 inode。
- 可以跨文件系统(因为只是路径引用)。
- 删除原文件后,软链接失效(变成“悬空链接”)。
- 可以链接目录。
创建软链接
bash
ln -s 源文件 软链接名
示例
bash
echo "World" > target.txt
ln -s target.txt symlink.txt
ls -l
硬链接 vs 软链接
特性 | 硬链接 | 软链接 |
---|---|---|
存储方式 | 直接指向 inode | 存储目标路径 |
跨文件系统 | ❌ 不支持 | ✅ 支持 |
删除原文件 | 仍然可用 | 失效 |
链接目录 | ❌ 不允许 | ✅ 允许 |
inode 相同 | ✅ 是 | ❌ 否 |
文件大小 | 与原文件相同 | 仅存储路径长度 |
分析日志文件
日志文件的作用
日志文件是用于记录 Linux 系统中各种运行信息的文件,相当于 Linux 主机的“日记”。 不同的日志文件记载了不同类型的信息,如 Linux 内核消息、用户登录事件、程序错误等。 日志文件对于诊断和解决系统中的问题很有帮助,因为在 Linux 系统中运行的程序通常 会把系统消息和错误消息写入相应的日志文件,这样系统一旦出现问题就会“有据可查”。 此外,当主机遭受攻击时,日志文件还可以帮助寻找攻击者留下的痕迹。
日志分类
内核及系统日志
在 6 以上的系统版本中,这种日志数据由系统服务 rsyslog 统一管理,根据其主配置文件/etc/rsyslog.conf
中的设置决定将内核消息及各种系统程序消息记录到什么位置。
/etc/rsyslog.conf :
- “.”:比后面等级要高(包含该等级)的都记录。例如:“*.info”
- “.=”:只记录该等级。例如:“.=debug”
- “!”:除了该等级都记录。例如:“!info”
- “-”:当有记录信息需要记录时,先存到缓存中,到一定大小时一次性写入,以减少对磁盘读写性能
- 的占用。例如:“-/var/log/maillog”
用户日志
用于记录 Linux 系统用户登录及退出系统的相关信息,包括用户名、登录的终端、登录 时间、来源主机、正在使用的进程操作等
程序日志
有些应用程序会选择由自己独立管理一份日志文件,而不是交给 rsyslog 服务管理,用 于记录本程序运行过程中的各种事件信息。
日志文件的位置
Linux 系统本身和大部分服务器程序的日志文件默认放在/var/log/
下。一部分程序共用 一个日志文件,一部分程序使用单个日志文件。而有些大型服务器程序日志由于日志文件不 止一个,所以会在/var/log/
目录中建立相应的子目录来存放日志文件,这样既保证了日志文 件目录的结构清晰,又可以快速定位日志文件。 有相当一部分日志只有 root
用户才有权限读取,这保证了相关日志信息的安全性。
常见的日志文件及查看方式
日志文件 | 存放内容 | 查看命令 |
---|---|---|
/var/log/messages | 内核消息及应用程序的公共日志(启动、I/O错误、网络错误、程序故障等) | cat 、tail -f |
/var/log/cron | crond 周期性计划任务的执行记录 | cat 、less |
/var/log/dmesg | 系统引导过程中的内核消息(硬件检测、驱动加载等) | cat 、dmesg |
/var/log/maillog | 邮件服务(Postfix/Sendmail)的收发记录 | cat 、grep "error" |
/var/log/lastlog | 每个用户最近的登录事件 | lastlog |
/var/log/secure | 用户认证相关事件(SSH登录、sudo使用、密码失败等) | cat 、grep "Failed" |
/var/log/wtmp | 用户登录、注销及系统启动/关机记录(二进制格式) | last 、who 、w |
/var/log/btmp | 失败的登录尝试记录(二进制格式) | lastb |
日志消息级别
级别 | 英文表示 | 中文翻译 | 意义 |
---|---|---|---|
0 | EMERG | 紧急 | 系统不可用(如内核崩溃、硬件故障) |
1 | ALERT | 警告 | 必须立即采取行动(如关键服务崩溃、磁盘满) |
2 | CRIT | 严重 | 严重错误(如数据损坏、系统组件失效) |
3 | ERR | 错误 | 常规错误(如服务启动失败、网络连接中断) |
4 | WARNING | 提醒 | 潜在问题(如高内存使用率、配置文件权限不当) |
5 | NOTICE | 注意 | 正常但需关注的事件(如用户登录、计划任务执行) |
6 | INFO | 信息 | 一般运行信息(如服务启动完成、定时备份成功) |
7 | DEBUG | 调试 | 开发/调试信息(如变量值、详细执行流程) |
8 | none | 无 | 不记录(用于关闭日志输出) |
日志文件分析
内核及系统消息日志
存放位置
/var/log/messages
(通用系统日志)/var/log/syslog
(Debian/Ubuntu)/var/log/kern.log
(内核专用日志)
内容解析
字段 | 说明 |
---|---|
时间标签 | 日志生成的日期和时间(如 Jan 1 12:00:00 ) |
主机名 | 生成日志的计算机名称(如 hostname ) |
子系统名 | 产生日志的应用程序或服务(如 kernel 、sshd 、nginx ) |
消息内容 | 具体事件描述(如 "Failed to mount /dev/sdb1: Invalid filesystem" ) |
常用命令
bash
cat /var/log/messages | grep -i error # 过滤错误日志
tail -f /var/log/syslog # 实时监控日志
journalctl -p err --since "2024-01-01" # 按优先级过滤(systemd 系统)
用户登录日志
存放位置
日志文件 | 记录内容 |
---|---|
/var/log/wtmp | 用户登录、注销及系统启停记录(二进制格式) |
/var/log/btmp | 失败的登录尝试(如暴力破解) |
/var/log/lastlog | 所有用户最近一次登录信息 |
查询命令
命令 | 功能 | 示例 |
---|---|---|
users | 显示当前登录的用户名(每会话一行) | users |
who | 显示当前登录用户的详细信息(终端、IP、登录时间) | who -a |
w | 显示当前用户及运行的进程 | w |
last | 查询成功登录记录(按时间倒序) | last -n 5 -i (显示最近5次登录的IP) |
lastlog | 显示所有用户最近一次登录时间 | lastlog -u root (仅查看root用户) |
lastb | 列出失败的登录尝试(用于排查入侵) | lastb -a (显示IP地址) |
选项说明:
-a
:显示登录来源主机名/IP-d
:将IP解析为主机名-R
:隐藏主机名/IP-n [数字]
:限制显示条目数
应用程序日志
存放位置
- 通常位于
/var/log/[服务名]/
目录下(如/var/log/nginx/
、/var/log/mysql/
) - 源码安装的服务可能自定义路径(如 Apache 默认在
/usr/local/apache2/logs/
)
示例:Apache 日志分析
bash
# 查看访问日志(实时监控)
tail -f /var/log/apache2/access.log
# 统计访问量最高的IP(前10)
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -10
# 过滤错误日志
grep -i "500" /var/log/apache2/error.log
日志分析注意事项
可疑现象排查
- 异常登录
- 非工作时间登录(如凌晨3点的root登录)
- 陌生IP地址登录(对比历史记录)
- 频繁失败登录
- 同一IP多次尝试失败(
lastb
检查)
- 同一IP多次尝试失败(
- 权限滥用
- 非管理员用户使用
sudo
(grep "sudo:" /var/log/auth.log
)
- 非管理员用户使用
- 服务异常重启
- 检查
/var/log/cron
或服务日志中的非计划重启记录
- 检查
日志保护措施
bash
# 防止日志被篡改(仅允许追加)
sudo chattr +a /var/log/messages
# 递归保护目录(如 /var/log/nginx/)
sudo chattr -R +a /var/log/nginx/
注意:
chattr +a
后,需用rm
或echo "" > file
会报错,必须通过logrotate
清理。echo "" >> file
追加不报错