lsof type

# `lsof` 中的文件类型(TYPE)及 FD 行为分析

`lsof` 命令输出的 `TYPE` 字段表示文件或资源的类型,而 `FD`(文件描述符)字段则描述了进程如何使用该资源。以下是详细解析:

## 一、`lsof` 中的主要 TYPE 类型

| TYPE 类型 | 说明 | 常见示例 |
|----------------|---------------------------------------------------------------------|----------|
| **REG** | 普通文件 | 数据文件、可执行文件 |
| **DIR** | 目录 | 工作目录 |
| **CHR** | 字符设备文件 | `/dev/null`, `/dev/tty` |
| **BLK** | 块设备文件 | `/dev/sda1` |
| **FIFO** | 命名管道(先进先出) | 进程间通信 |
| **unix** | UNIX 域套接字(本地进程通信) | `type=STREAM`/`DGRAM` |
| **IPv4/IPv6** | 网络套接字(TCP/UDP) | `TCP *:ssh` |
| **sock** | 通用套接字(可能是网络或本地) | 未指定具体协议时 |
| **PIPE** | 匿名管道 | 进程间通信 |
| **DEL** | 已删除但仍被进程打开的文件 | 日志文件被删除但进程仍写入 |
| **KQUEUE** | BSD 事件通知机制 | FreeBSD/MacOS 特有 |
| **PSXSHM** | POSIX 共享内存 | 进程间共享内存 |
| **SHM** | System V 共享内存 | 进程间共享内存 |

## 二、FD(文件描述符)字段解析

FD 字段格式通常为:`数字+访问模式`,例如 `4u`、`3r`、`1w`

### 1. 数字部分
- **0,1,2**:标准输入、输出、错误
- **3+**:进程打开的其他文件描述符

### 2. 访问模式
| 模式 | 说明 | 示例 |
|------|-------------------------|------------|
| `r` | 只读模式打开 | `3r` |
| `w` | 只写模式打开 | `1w` |
| `u` | 读写模式打开 | `4u` |
| ` ` | 未指定模式(空格) | `5 ` |
| `-` | 标准错误(stderr) | `2w` |
| `c` | 当前工作目录 | `cwd` |
| `txt`| 程序代码(文本段) | `txt` |
| `mem`| 内存映射文件 | `mem` |

## 三、如何根据 FD 和 TYPE 分析具体行为

### 案例 1:网络套接字分析
```bash
sshd 1234 root 3u IPv4 0xffff800001234 0t0 TCP *:ssh (LISTEN)
```
- **TYPE=IPv4**:IPv4 网络套接字
- **FD=3u**:文件描述符 3,读写模式
- **TCP *:ssh**:监听所有接口的 SSH 端口
- **行为**:SSH 守护进程正在监听连接

### 案例 2:UNIX 域套接字
```bash
docker 5678 root 5u unix 0xffff800005678 0t0 type=STREAM
```
- **TYPE=unix**:本地进程间通信
- **type=STREAM**:面向连接(类似 TCP)
- **FD=5u**:文件描述符 5,读写模式
- **行为**:Docker 守护进程通过该 socket 接受本地连接

### 案例 3:已删除文件
```bash
nginx 9012 www-data 4w REG 8,1 0 123456 /var/log/nginx/access.log (deleted)
```
- **TYPE=REG**:普通文件
- **(deleted)**:文件已删除
- **FD=4w**:文件描述符 4,只写模式
- **行为**:Nginx 仍在向已删除的日志文件写入

## 四、高级分析方法

### 1. 查看具体 socket 连接信息
```bash
# 查看所有网络连接
lsof -i

# 查看特定进程的 TCP 连接
lsof -p <PID> -i TCP

# 查看监听端口
lsof -i -s TCP:LISTEN
```

### 2. 查看 UNIX 域套接字对端
```bash
# 获取 socket inode
ls -l /proc/<PID>/fd/ | grep socket

# 查找连接的另一端
find /proc/*/fd -ls 2>/dev/null | grep <inode>
```

### 3. 查看文件描述符详细信息
```bash
# 查看进程打开的所有 FD
ls -l /proc/<PID>/fd/

# 查看某个 FD 的详细信息
readlink /proc/<PID>/fd/<FD>
```

## 五、常见问题排查

### Q1:如何知道某个 socket 是客户端还是服务端?
- **LISTEN** 状态:服务端
- **ESTABLISHED** 状态:已建立连接
- 无状态显示+远程地址:客户端

### Q2:`type=STREAM` 和 `type=DGRAM` 的区别?
- **STREAM**:可靠、有序(TCP/UNIX stream)
- **DGRAM**:不可靠、无序(UDP/UNIX datagram)

### Q3:为什么有些文件显示 (deleted)?
表示文件已被删除,但仍有进程保持打开状态,直到进程关闭该文件描述符才会真正释放空间。

通过结合 TYPE 和 FD 信息,您可以准确判断进程正在进行的文件操作、网络通信或 IPC 行为。

posted on 2025-07-11 09:55  吃草的青蛙  阅读(27)  评论(0)    收藏  举报

导航