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

Linux下如何以非hack方式获取所有子进程的PID?

如何在Linux下简洁获取指定父进程的子进程PID列表?

方案1:直接读取/proc文件系统(推荐)

Linux的/proc文件系统是内核暴露进程信息的原生接口,完全不需要调用外部命令,也不会产生额外进程干扰,是最简洁可靠的方法。

每个进程在/proc下对应一个以PID命名的目录,目录内的stat文件第4个字段就是该进程的父进程PID(PPID)。我们只需要遍历/proc下的数字目录,读取每个进程的stat文件,对比PPID是否匹配目标父进程即可。

示例C代码:

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>

void get_child_pids(pid_t parent_pid, pid_t *child_pids, size_t *count) {
    DIR *proc_dir = opendir("/proc");
    if (!proc_dir) return;

    struct dirent *entry;
    *count = 0;

    while ((entry = readdir(proc_dir)) != NULL) {
        // 跳过非数字命名的目录(只有进程PID是数字目录)
        if (!isdigit(entry->d_name[0])) continue;

        pid_t current_pid = atoi(entry->d_name);
        if (current_pid == parent_pid) continue; // 跳过父进程自身

        char stat_path[256];
        snprintf(stat_path, sizeof(stat_path), "/proc/%d/stat", current_pid);

        FILE *stat_file = fopen(stat_path, "r");
        if (!stat_file) continue;

        int ppid;
        // 读取stat文件的第4个字段(PPID),忽略前面的PID、进程名、状态字段
        fscanf(stat_file, "%*d %*s %*c %d", &ppid);
        fclose(stat_file);

        if (ppid == parent_pid) {
            child_pids[(*count)++] = current_pid;
        }
    }

    closedir(proc_dir);
}

// 用法示例
int main() {
    pid_t target_parent_pid = getpid(); // 替换为你的目标父进程PID
    pid_t child_pids[10]; // 根据实际需求调整数组大小
    size_t child_count = 0;

    get_child_pids(target_parent_pid, child_pids, &child_count);

    printf("找到的子进程PID:\n");
    for (size_t i = 0; i < child_count; i++) {
        printf("%d\n", child_pids[i]);
    }

    return 0;
}

方案2:改进popen调用(快速实现)

如果不想写太多文件系统操作的代码,可以改进原来的popen方案,直接在命令行里排除运行pgrep的shell进程:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void get_child_pids_via_pgrep(pid_t parent_pid, pid_t *child_pids, size_t *count) {
    char cmd[256];
    // 在命令中用grep -v $$排除当前shell进程的PID
    snprintf(cmd, sizeof(cmd), "pgrep -P %d | grep -v $$", parent_pid);

    FILE *cmd_output = popen(cmd, "r");
    if (!cmd_output) return;

    *count = 0;
    char pid_str[32];
    while (fgets(pid_str, sizeof(pid_str), cmd_output) != NULL) {
        pid_t pid = atoi(pid_str);
        if (pid > 0) {
            child_pids[(*count)++] = pid;
        }
    }

    pclose(cmd_output);
}

这里的$$是shell的内置变量,代表当前shell进程的PID,用grep -v $$就能直接过滤掉pgrep所在的shell进程,不需要后续手动解析排除。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:58:37