%%
# 纲要
> 主干纲要、Hint/线索/路标
# Q&A
#### 已明确
#### 待明确
> 当下仍存有的疑惑
**❓<font color="#c0504d"> 有什么问题?</font>**
# Buffer
## 闪念
> sudden idea
## 候选资料
> Read it later
%%
# 查看系统信息
#### 查看计算机名称
- `$ hostname`: 查看**计算机名称**
#### 查看操作系统信息
- `$ uname [OPTION]`:查看**操作系统名称**
- `-a`:查看所有系统信息
- `-s`:查看内核名
- `-r`:查看内核版本(release)
- `-v`:查看系统版本
> [!info]
>
> `uname` 显示信息
> `uname` 显示信息:内核名、主机名、内核版本、系统版本、机器架构、处理器架构、操作系统名
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-B5FCAB3E87E4EF1FB7489D9FD733C497.png|850]]
>
> 以上图为例:
>
> - `Linux`:内核名
> - `ubuntu`:主机名(hostname)
> - `5.15.0-94-generic`:内核版本
> - `#104~20.04.1-Ubuntu SMP Tue Jan 16:13:34:09 UTC 204`:系统版本,其中 `#104` 表示编译了内核 `5.15.0-94-generic` 104 次,日期为最后编译的时间戳。
> - `x86_64`:机器架构
> - `x86_64`:处理器架构
> - `GNU/Linux`:操作系统名
> [!NOTE] Linux 内核版本号
>
> 以 `5.15.0-94-generic` 为例,共 5 个字段
>
> - 内核版本(主版本):`5`
> - 次要版本:`15`
> - 轻微修订:`0`
> - 错误修复:`94`
> - 桌面/服务器版本标识:`generic` 桌面版; `server` 表示服务器版本
#### 查看内核版本号
两种命令:`uname -r` 或 `cat /proc/version`
![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-5042EDBE84F3F5E19287A966793A7796.png|578]]
#### 查看系统已运行时间
两种命令:`uptime` 或 `cat /proc/uptime`
![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-91969D070040B30CB717CAA49BCEBE91.png|539]]
#### 查看内存使用情况——free
`free`: 查看内存使用概况
- `-h`:以**易读单位**显示,如 MB、GB(human-readable)
> [!NOTE] 字段说明
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-CFFFF396D4934A80010C55DD0898A86E.png|606]]
>
> - shared:共享内存
> - free:**空闲的物理内存**(完全未使用的)
> - buff/cache:被内核用作**块缓存**、**Page Cache** 的内存;
> - available:**总可用内存**(≈ free + 可回收的 cache/buffer - 不可回收的内存)
> [!tip] `top` 也可实时监测内存使用情况,其中 `%MEM` 字段为内存使用占比,`RES` 为物理内存的实际占用大小。
> [!tip] `cat /proc/meminfo` 可查看内存的详细统计信息
#### 查看内存详细占用——cat /proc/meminfo
![[_attachment/02-开发笔记/05-操作系统/内存管理/内存管理.assets/IMG-内存管理-3A9FC24DF0F30EBEACCD44706472A4E4.png|257]]
#### 字段说明
> [!info] 可在 `man 5 proc` 中定位 `meminfo` 查看具体含义
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-D2D9AF7C81AA86621B544671C768675C.png|591]]
| 字段 | 说明 |
| ----------- | --------------------------------------------------------------------- |
| Buffers | 缓冲块设备的元数据; |
| Cached | **页缓存 Page Cache** |
| SwapCached | Page Cache 中被 "**曾经**" 被交换到 swap file,尽管已交换回内存,但仍残留于 swap file 中的副本部分 |
| | |
| Mlocked | **被用户进程锁住的内存页**(如调用 `mlock()` ) |
| Unevictable | **不可回收的页**(例如被锁住的页) |
| | |
| Dirty | **脏页**,即 Page Cache 中**被修改,而尚未写回磁盘**的部分。 |
| Writeback | 正在被异步 "**回写**" 到磁盘的数据量 |
| | |
| Mapped | 文件映射的内容(mmap 映射的) |
| Shmem | 共享内存 |
> [!NOTE] Active 字段是 "**总活跃页**",包括两部分:
>
> - `Active(anon)`:匿名活跃页,进程的运行时内存空间,即堆、栈内存等。
> - `Active(file)`:文件活跃页,即 **Page Cache 中的热页**。
>
<br><br><br>
# 查看硬件设备信息
#### 查看 CPU 信息
- `$ lscpu`:查看 CPU 信息
- `$ cat /proc/cpuinfo`: 查看 CPU 信息(详细,**具体到每个核**)
- `$ nproc`:直接输出 **CPU 核心总数**
#### 查看 GPU 信息
- `$ nvidia-smi`: 查看 NVIDA 显卡信息(显卡型号、使用情况)
<br><br>
# 查看系统与进程信息 (`/proc/xxx` )
#### 查看系统相关信息(`/proc/`)
`cat` 可查看以下**系统资源与内核信息**:
| | 说明 |
| ---------------- | --------------------------- |
| /proc/cpuinfo | CPU 信息(型号、核心数、频率) |
| /proc/meminfo | 内存使用情况(总量、可用、缓冲区等) |
| /proc/uptime | 内核运行时间、空闲时间(秒) |
| /proc/loadavg | 系统负载(过去 1 / 5 / 15 分钟的平均负载) |
| /proc/version | 内核版本和编译信息 |
| /proc/swaps | 当前系统的 swap 分区或文件信息 |
| /proc/partitions | 所有磁盘分区信息 |
| /proc/mounts | 已挂载设备、挂载点 |
| /proc/devices | 设备(字符设备、块设备) |
#### 查看进程相关信息(`/proc/<pid>/`)
`cat` 可查看**指定进程**的相关信息:
| | 说明 |
| ---------------------- | -------------------------------------------------- |
| `/proc/<pid>/status` | 进程状态(包括 UID、线程数、内存占用、权限等) |
| `/proc/<pid>/cmdline` | 启动该进程的命令行参数(以空字符分隔) |
| `/proc/<pid>/comm` | **可执行文件名** |
| `/proc/<pid>/limits` | **进程的资源限制** |
| `/proc/<pid>/io` | I/O 读写统计信息 |
| `/proc/<pid>/maps` | 进程的**虚拟内存映射**情况,即**内存空间布局**。等价命令 `sudo pmap <pid>` |
| `/proc/<pid>/envirion` | 环境变量(变量间以 `\0` 分隔) |
注意,部分文件是 "**符号连接**" 形式,不能由 `cat` 查看,可使用 `ls` 查看目录内容或 `ls -l` 查看具体链接目标:
| | 说明 |
| ----------------------- | ---------------------------------- |
| `ls -l /proc/<pid>/cwd` | 查看进程**当前工作目录**(符号链接形式) |
| `ls -l /proc/<pid>/exe` | **可执行文件的完整绝对路径**(符号链接形式) |
| `ls /proc/<pid>/fd` | 查看进程**打开的所有文件描述符**(每一项都是符号链接形式) |
| `ls /proc/<pid>/task` | 查看进程的**所有线程**(每个线程 ID 对应一个**子目录**) |
> [!tip] 使用 "命令替换" 简化步骤,按进程名查看指定进程信息
>
> `cat /proc/$(pgrep process_name | head -n1)/status`
>
> 示例:查看进程当前线程数量
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-F15574F53D3906639C7B39B15ABD8B57.png|776]]
>
>
> [!example] 统计系统总进程数量
>
> `ls /proc | grep '^[0-9]' | wc -l`
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-DCC134F7FC36506A30D56B3288B71609.png|603]]
>
> [!example] 查看进程当前工作目录、可执行文件路径
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-A39D3CD9F25B2643F950ECE52BC26022.png|802]]
>
> [!example] 查看进程打开的**所有文件描述符**
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-1027D4B9266AC9D9C43CA8C0E5E07768.png|535]]
>
> [!example] 查看进程打开的 **所有 socket**
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-F83AECDC53401136FB42DF35C590159D.png|816]]
>
> [!example] 查看进程的所有线程
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-0B09A53F0AE76ED52BCE3380CF53E7D3.png|802]]
> [!example] 查看进程的虚拟内存地址空间
>
> 两个命令 `sudo cat /proc/<pid>/maps` 或 `sudo pmap <pid>`,等价
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-9C983D511A5E3C509752D263E4F22FD4.png|839]]
>
> 查看进程中 "各个**线程的栈**" 地址段:
>
> ```shell
> pid=1234
> for tid in $(ls /proc/$pid/task); do
> echo "Thread $tid stack:"
> grep '\[stack\]' /proc/$pid/task/$tid/maps
> done
> ```
>
#### 查看网络相关信息(`/proc/net/`)
`cat` 可**查看**网络状态相关信息:
| | 说明 |
| --------------- | ----------------------------- |
| /proc/net/tcp | 当前 TCP 连接(16 进制显示的 IP 地址&端口号) |
| /proc/net/udp | 当前 UDP 连接 |
| /proc/net/dev | 每个网络接口的收发包字节数等 |
| /proc/net/route | 路由表 |
> [!example]
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-5119166C6A050486147B8ED0F1CB689E.png|791]]
<br><br>
# 查看/修改内核参数 ⭐——sysctl
`sysctl [options] [var[=val]`: 用于查看、修改内核参数
- `-a`:查看所有内核参数
- `-n`:只显示**数值**,不显示参数名
- `-w`:**临时修改** 内核参数(仅此次系统运行期间有效,重启后失效);**需 `root`权限**
- `-p[FILE]`:从**指定配置文件**加载内核参数(默认文件是 `/etc/sysctl.conf`)
- `--system`:从**所有系统配置文件**加载内核参数(包括 `/etc/sysctl.d/*.conf`)
> [!info] "`sysctl` 命令" 背后的实现即是**读写 `/proc/sys/` 下的虚拟文件**
>
> 可用 `sudo strace sysctl -w net.ipv4.ip_forward=1` 跟踪**查看 sysctl 命令背后执行的系统调用**,其中可见如下语句:
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-B77553B888AB40735252EEB9362AE54E.png|629]]
>
> [!example] 示例:`sysctl net.ipv4.tcp_rmem` 等同于 `cat /proc/sys/net/ipv4/tcp_rmem`
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-6864A1F60AEB1695BB7E19079931E259.png|375]]
>
使用示例:
```shell
# 查看内核参数: TCP接收缓冲区大小
sysctl net.ipv4.tcp_rmem # 等于 cat /proc/sys/net/ipv4/tcp_rmem
# 修改core dump文件名
sudo sysctl -w kernel.core_pattern=core.%p.%e.%s.%t
# 修改/etc/sysctl.conf后, 加载其中参数, 使立即生效
sudo sysctl -p
# 修改or新增/etc/sysctl.d/*.conf后, 使立即生效
sudo sysctl --system
```
<br>
## 修改内核参数的几种方式
修改有以下几种方式:
1. **临时修改**(此次系统运行期间有效,系统重启后失效):
- 方式一:通过 **==`sysctl -w` 命令==** 设置(该工具本质上就是去读写 `/proc/sys/` 下的虚拟文件)
- 方式二:通过直接 **写入 ==`/proc/sys/xxx`== 文件** 修改
2. **永久修改**:
- 方式一:编辑 **==`/etc/sysctl.conf` 配置文件==**
- (修改后通过 `sudo sysctl -p` 使立即生效,或重启后生效)
- 方式二:编辑 `/etc/sysctl.d/*.conf` 配置文件
- (修改后通过 `sudo sysctl --system` 使立即生效,或重启后生效)
> [!tip] "`/proc/sys/xx.yy`文件" 对应 "`/etc/sysctl.conf` 中的 `xx.yy` 变量"
>
> 例如 `/proc/sys/kernel/core_pattern` 对应 "`/etc/sysctl.conf` 中的 `kernel.core_pattern` 变量"
>
> [!example] 示例:开启 IPv4 转发
>
> ```shell
> # 临时修改(两种等价方式)
> # 方式一:
> sudo sysctl -w net.ipv4.ip_forward=1
> # 方式二:
> echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
>
> # 永久修改
> sudo vim /etc/sysctl.conf # 打开文件后添加内容: net.ipv4.ip_forward = 1;
> sudo sysctl -p # 使配置文件的变更立即生效
> ```
>
>
<br>
### (1)通过编辑 `/etc/sysctl.conf` 或 `/etc/systcl.d/*.conf` 文件永久修改
`/etc/sysctl.conf` 是 Linux 中用于配置 **==内核参数==**(kernel parameters)的配置文件,涉及**进程管理、内存管理、网络协议栈、安全机制等**方面的行为。
该文件中的设置在**系统启动时**或通过 **`sysctl` 命令** 可被加载到内核中,使这些参数立即生效。
该文件中每一行代表一个配置项,为 `key = value` 的格式,例如:
```shell title=/etc/sysctl.conf
net.ipv4.ip_forward = 1 # 开启IPV4转发
net.core.somaxconn = 1024 # 设置listen()的backlog上限
fs.file-max = 2097512 # 设置系统允许同时打开的最大文件描述符数量
kernel.core_pattern = core.%p.%e.%s.%t # 设置coredump文件名格式
```
> [!example] `/etc/sysctl.conf` 文件示例
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-A124085F94871EEF2FBDC8920AEAAEF7.png|512]]
> [!tip] 建议:可在 `/etc/sysctl.d/` 路径下新建独立配置文件,例如 `/etc/sysctl.d/99-custom.conf`
<br>
### (2)通过 sysctl 命令或写入 `/proc/sys/xxx` 临时修改
`/proc/sys/` 是 Linux 内核暴露的用于 **动态查看和配置内核参数** 的接口,涵盖网络、文件、虚拟内存、安全、进程等多方面的行为控制。
> [!NOTE] /proc/sys/ 下的虚拟文件是内核参数的实时映射,**==写入值后立即生效==**(但仅在此次系统运行期间有效)
## 常用内核参数
通过 cat 命令可查看下列内核参数,也可向**该文件写入**实现修改。
| | 说明 | 值 |
| ------------------------------------- | ----------------------------- | ---------- |
| `/proc/sys/kernel/core_pattern` | core dump 文件命名规则 | 默认 4194304 |
| `/proc/sys/kernel/pid_max` | 系统 **最大 PID** (所能同时运行的最大进程数量) | |
| `/proc/sys/kernel/threads-max` | 系统 **最大线程数**(整个系统级别,而不是单进程) | |
| `/proc/sys/kernel/ns_last_pid` | 下一个新进程的 PID | |
| `/proc/sys/kernel/randomize_va_space` | 地址空间随机化(ASLR) | 2 表示完全开启 |
| `/proc/sys/kernel/yama/ptrace_scope` | 限制 ptrace | 0-3,默认 1 |
> [!example] 示例
>
> 示例一:设置 core dump 文件名格式
>
> - 方式 1:`sudo sysctl -w kernel.core_pattern="core.%p.%e.%s.%t"`
> - 方式 2:`echo "core.%p.%e.%s.%t" > /proc/sys/kernel/core_pattern`
>
> 示例二:开启 IP 转发
>
> - 方式 1:`sudo sysctl -w net.ipv4.ip_forward=1`
> - 方式 2:`echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward`
>
##### 文件系统相关
| | 说明 |
| ----------------------- | -------------------------------------------------------------------------- |
| `/proc/sys/fs/file-max` | 系统中**允许同时打开的最大文件描述符总数**(包括 socket、pipe、设备等),即内核 **file table(文件句柄表)的最大项数** |
| `/proc/sys/fs/nr_open` | 单个进程**允许打开的最大文件描述符数**(硬上限,ulimit -n 设置的软上限不允许超过该值) |
##### 网络相关
| | 说明 | 值 |
| ------------------------------------------ | ------------------------ | ------ |
| `/proc/sys/net/ipv4/ip_forward` | 控制是否允许 IPv4 转发 | 0 \| 1 |
| `/proc/sys/net/core/somaxconn` | socket 最大 listen backlog | |
| `/proc/sys/net/ipv4/tcp_tw_reuse` | 是否允许 TIME_WAIT 状态的套接字被重用 | |
| `/proc/sys/net/netfilter/nf_conntrack_max` | 最大连接跟踪表项数(防火墙) | |
> [!info] `/proc/sys/net` 与 `/proc/net` 的区别
>
> - **`/proc/net` 是 "网络状态信息" ==查看==接口**;例如,用于监控服务器 TCP 连接数、吞吐量, 丢包情况等。
> - **`/proc/sys/net` 是 "网络内核参数" ==配置==接口**;例如,修改 TCP 栈、接口行为、防火墙策略等 tunable 参数
>
<br><br>
# 查看/修改进程资源限制 🐢 ⭐——ulimit
有以下两种方式:
1. **临时修改**(仅**当前 shell 会话及其子进程**中有效):通过 **`ulimit` 命令**
2. **永久修改**:修改 `/etc/security/limits.conf` 或 `/etc/security/limits.d/*.conf` 文件
- 注:此方式 **仅对使用 PAM 启动的登录 shell 或服务生效**。对于 systemd 服务则需要额外设置。
> [!example] 示例:永久设置用户级 "软/硬限制"
>
> ```shell title:/etc/security/limits.conf
> # 用户级软硬限制, 在PAM层面针对登录shell生效.
> # 这里指定的是"用户级" 配置, 其上限无法超过系统级配置, 例如/proc/sys/fs/nr_open
>
> # 为指定用户设置
> douglas soft nofile 65535
> douglas hard nofile 65535
>
> # 为所有用户设置
> * soft nofile 65535
> * hard nofile 65535
> ```
>
<br>
### (1)通过 `ulimit` 修改 "当前 shell 会话" 中的进程资源限制
命令:`$ ulimit [option] [limit]`
- `-c [limit]`:查看/设置 **core dump 文件大小**;
- `-u [limit]`:查看/设置**当前用户**在 shell 会话中**可创建的最大进程数**
- (不仅限于当前 shell 会话中,而是**该用户整个的总进程数**,包括所有终端、后台任务、fork出来的子进程都算)
- `-n [limit]`:查看/设置可打开的**最大文件描述符数量**;
- `-s [limit]`:查看/设置**栈大小**(默认 8192 **KB**,即 8MB)
- `-S`:针对**软**限制(soft limit)。缺省默认就是操作软限制。
- `-H`:针对**硬**限制(hard limit)
- `-a`:查看所有限制值
> [!NOTE] `-S` 与 `-H` 搭配其他选项使用,例如 `ulimit -Hn <limit>` **查看/设置文件描述符硬限制**。
> [!important] 关于进程资源的 "硬限制" 与 "软限制"
>
> - **硬限制**规定了 "**软限制**" 的上限,只有 **root 用户** 可以修改硬限制的值。
> - 软限制是 "**当前实际限制**",普通用户仅可以通过 **==ulimit 命令==** 在当前 shell 会话中 **临时提升 "==软限制=="**(软限制值无法超过硬限制)
> - 即普通用户仅能使用 `ulimit -n <limit>` 或 `ulimit -Sn <limit>` 提升软限制,或**通过 `ulimit -Hn` "==仅查看==" 硬限制**。
> - 需要 root 权限才能**执行 `ulimit -Hn <limit>` ==修改==硬限制**。
>
>
> 进程资源限制由几个不同层级的控制项决定。以 "**能同时打开的最大文件描述符数量**" 为例:
>
> | 控制项 | 作用范围 | 值含义 | 说明 | 修改所需权限 |
> | --------------------------- | ------- | ------------------ | ------------------------------------------ | ----------------- |
> | `/proc/sys/fs/file-max` | 系统级 | 所有进程打开总和的上限 | **==整个系统==** 中最多能同时打开 fd 的上限 | root |
> | `/proc/sys/fs/nr_open` | 系统级 | 单个进程的 "**硬限制**" 上限 | **==单个进程==** 最多能同时打开 fd 的上限 | root |
> | `/etc/security/limits.conf` | 用户级 | 单个用户的 "**软/硬限制**" | **==单个用户下所有进程==** 能同时打开的 fd 总和,即用户登录后默认的配置 | root |
> | `ulimit -n/-Sn/-Hn` | shell 级 | 单个进程的 "**软/硬限制**" | 只对 **当前 shell 会话及其子进程** 有效 | 硬限制 `-Hn` 需要 root |
> ^01rvkd
> [!quote] shell 内置命令 `ulimit` 的作用
>
> 在 Linux 中,每个用户进程都受到一组资源限制,例如:
>
> - 可打开的最大文件描述符数
> - 最大可用内存
> - 栈大小
> - 最大可创建进程数
> - CPU 时间限制
> - 核心转储文件大小限制(core file)
>
> 这些限制由内核维护,**`ulimit` 提供了一个用户态的接口**,用来查询或修改这些限制。
>
> `ulimit -a` 可查看当前的所有限制值,如下图:
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-A79C84318AE8B36D028F95E6D27121ED.png|428]]
>
>
<br>
### (2)通过编辑 `/etc/security/limits.conf` 或 `/etc/security/limits.d/*.conf` 文件永久修改
略。
<br><br><br>
# 查看系统中已打开的文件对象⭐——lsof
> list open files
`lsof` 命令用于查看整个系统中 "**打开的文件对象**" 的信息(list open files),可按进程、用户、文件、端口、协议等条件**过滤**。
命令:`lsof [option]`,默认列出
选项:
- `-p <pid>`:查看特定进程的(按 **PID** 筛选)
- `-c <command>`:查看特定进程的(按**启动命令行**筛选)
- `-u <username>`: 查看特定用户的
- `-t`:仅输出 PID
- `-n`:禁止解析主机名(默认会将 IP 解析为域名,会进行 DNS 查询)
- `-P`:禁止解析端口名(默认会进行端口号->服务名的解析,例如 `:80` 显示 `:http`,`:22` 显示为`:ssh`)
- `-a`:指定**多个选项时取 "and"** (默认是 "or")
- `+d <dir>`:列出打开了该目录下(不递归)文件的进程
- `+D <dir>`:列出打开了该目录下(递归)文件的进程
- `-d <FD>`:查看**特定类型的文件描述符** (例如 `mem`, `txt`,`cwd` 等)或 **查看指定文件描述符**(输入序号)
- `-i[<protocal>][@<hostname|hostaddr>][:<port>]`:查看 **==网络连接==** 信息,可指定协议(TCP/UDP)、IP 地址或域名、端口号
- `-sTCP:<state>`:查看指定 TCP 状态的连接
> [!info] lsof 命令背后的实现是读取 `/proc/<pid>/*` 信息,再按要求呈现。
>
> 包括 `/proc/<pid>/<cwd, exe, maps, fd, net/tcp>` 等等。
> [!example] 示例:`lsof -a -p $ -d 0, 1, 2`
>
> 
>
> 注:
>
> 
>
>
<br>
## (1)进程打开文件相关
###### 查看指定进程或用户打开的所有文件
```shell
# 查看进程PID=22434打开的所有文件
sudo lsof -p 22434
# 查看进程http_server打开的所有文件
sudo lsof -c http_server
# 查看用户douglas的进程打开的所有文件
sudo lsof -u douglas
# 查看指定进程映射的共享库
sudo lsof -p <pid> -d mem -a # 注意带-a! 否则多选项是or关系
```
###### 查看指定文件或指定目录下文件被打开情况
```shell
# 查看占用指定文件的进程
sudo lsof /path/to/file
# 查看打开了/tmp目录的所有进程
sudo lsof +d /tmp # 不递归检查子目录
# 查看打开了/var/www目录的所有进程
sudo lsof +D /var/www # 递归检查子目录
```
> [!tip] `-t` 只输出 PID,通常搭配其他命令使用
>
> 例如,关闭占用 80 端口的进程:`kill -9 $(sudo lsof -t -i :80)`
> [!important] 查看指定进程打开的文件对象信息:
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-AE13D3245637B842C58717B995415851.png|650]]
>
>
> lsof 显示了进程打开的**所有 “文件对象”**,不仅包括 fd,还会包括以下内容:
>
> | | 说明 |
> | ------ | --------------------------------- |
> | `cwd` | 当前工作目录(current working directory) |
> | `txt` | 进程正在执行的二进制程序代码(text segment) |
> | `mem` | 加载到内存的库(包括共享库,mmap 映射的内存) |
> | `rtd` | 根目录(root directory) |
> | `DEL` | 被删除但尚未关闭的文件(文件描述符泄露?) |
> | `NOFD` | 无文件描述符但被引用的对象 |
>
> 因此,可用于**分析共享内存、文件描述符泄露、确定服务监听状态**等。
<br>
## (2)网络信息相关——`lsof -i`
`lsof -i` 使用示例(需要 **root 权限**)
```shell
# 查看所有网络连接
sudo lsof -i
# 查看所有TCP/UDP连接
sudo lsof -iTCP
sudo lsof -iUDP
# 查看指定端口的使用情况
sudo lsof -i :80 # 指定80端口
# 查看与指定IP地址的连接
sudo lsof
[email protected]
sudo lsof
[email protected]:80 # 指定IP地址+端口
sudo lsof
[email protected]:80 # 指定协议+IP地址+端口
# 查看指定状态的TCP连接
sudo lsof -i -sTCP:LISTEN # 处理LISTEN的TCP服务
```
> [!tip] `-n` 与 `-P` 禁用解析,在涉及大量连接时,可显著提升输出速度。
>
> 示例:`lsof -nP -iTCP`
> [!example]
>
> - 查看所有连接、查看指定端口状态、查看处于 LISTEN 的 TCP 服务
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-4C4D849467FDBA80B51E07C40F5363B5.png|704]]
>
> - 查看与指定地址的连接
>
> ![[_attachment/02-开发笔记/11-Linux/Linux 命令行/Linux-系统信息相关命令.assets/IMG-Linux-系统信息相关命令-311DA239371099C384915DEDAC09466F.png|701]]
>
<br><br>
# 查看系统日志
##### 查看系统启动日志
- `$ dmesg` 查看系统启动日志 🔴
- `$ dmesg | less`
<br><br><br>
# 参考资料
# Footnotes