You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何忽略read_dir读取/proc/[pid]/fd时创建的文件描述符?

解决/proc/[pid]/fd遍历中包含read_dir自身FD的问题

直接pop最后一个元素的做法完全不可靠——proc文件系统的目录遍历顺序没有任何保证,那个额外的FD未必会出现在列表末尾。正确的做法是在遍历过程中跳过read_dir自身对应的文件描述符,具体实现如下:

核心思路

当你调用read_dir打开/proc/[pid]/fd目录时,这个操作会在当前进程中创建一个新的FD(指向该目录)。如果是读取自身进程的FD(/proc/self/fd),这个新FD会被包含在遍历结果里;如果是读取其他进程的FD,这个FD属于当前进程,不会出现在目标进程的FD列表中,所以跳过操作不会影响结果。

Rust代码实现

use std::fs::read_dir;
use std::os::unix::io::AsRawFd;
use std::io;

fn list_fds(pid: u32) -> io::Result<Vec<i32>> {
    let fd_dir_path = format!("/proc/{}/fd", pid);
    // 打开目标FD目录,获取ReadDir实例
    let mut dir_iterator = read_dir(fd_dir_path)?;
    // 获取这个ReadDir自身对应的文件描述符
    let dir_self_fd = dir_iterator.as_raw_fd();

    let mut fds = Vec::new();
    while let Some(entry) = dir_iterator.next() {
        let entry = entry?;
        // 将目录项名称转为字符串(即FD数字)
        let fd_str = entry.file_name().into_string().map_err(|_| {
            io::Error::new(io::ErrorKind::InvalidData, "无法解析FD名称")
        })?;
        if let Ok(fd) = fd_str.parse::<i32>() {
            // 跳过read_dir自身的FD
            if fd != dir_self_fd {
                fds.push(fd);
            }
        }
    }

    Ok(fds)
}

其他注意事项

  • 如果你只需要读取自身进程的FD,也可以先在打开read_dir前通过一次遍历获取初始FD列表,但这种方法需要两次IO操作,效率不如直接跳过目标FD。
  • 处理/proc文件系统时要注意权限问题:如果目标进程不属于当前用户,你可能没有权限读取其fd目录。

内容的提问来源于stack exchange,提问作者jz steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:07:26