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
相关产品推荐
相关产品推荐

