linux 下根据PID查找服务信息

"这篇博客介绍了如何在Linux环境下通过PID查找服务名称以及根据服务名称找PID的方法。文章提到,Linux中的服务信息存储在/proc目录下以PID为名的文件夹中,服务名称位于status文件的第一行。通过读取并解析/proc/${pid}
摘要由CSDN通过智能技术生成

最近在 linux 下需要实现2个函数

  • 通过 pid服务名称
  • 根据 服务名称pid

根据 pid 查找服务名称

首先需要知道 Linux 所有的信息其实都是以文件形式来呈现
而运行的服务信息保存在 /proc 路径下以 pid 作为文件夹的各种文件中

在这里插入图片描述

其中我们需要的服务名称信息保存在 status 文件里,并且服务名称就在文件的第一行,想办法解析出来即可

status 中的部分内容

所以通过 pid 查找服务名称很简单

  • 尝试读取 /proc/${pid}/status,如果读不到,说明该服务不存在
  • 如果存在尝试读取第一行数据,读不到,也说明不对
  • 最后解析第一行数据里的服务名

解析过程也是需要注意的,以 "Name: systemd" 为例,":" 后面其实是一个制表符,如果我们用 cat /proc/1/status -A,查看一下,得到的结果是:

Name:^Isystemd$
Umask:^I0000$
...

其中 "^I" 代表制表符, "$" 代表换行符,所以切割的思路很多

  • sscanf 函数,类似与正则匹配最简单
  • std::string 通过 find 函数找到 ":" 位置后,利用 substr 函数切割,注意多了一个制表符

所以接下来的代码很好写

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

#define MAX_PATH 260
#define BUF_SIZE 1024

bool findNameByPid(const int &pid, std::string &servername)
{
    char buf[BUF_SIZE];
    char name[MAX_PATH];
    char filepath[MAX_PATH];

    sprintf(filepath, "/proc/%d/status", pid);
    FILE *fp = fopen(filepath, "r");
    if (nullptr == fp)
        return false;

    if (fgets(buf, BUF_SIZE - 1, fp) == nullptr)
    {
        fclose(fp);
        return false;
    }
    fclose(fp);

    sscanf(buf, "%*s%s", name);
    servername = std::string(name);
    return true;
}

根据服务名找服务 pid

使用服务名找 pid 稍微复杂一点
因为需要遍历 proc 文件夹下所有进程下的 status 文件里的服务名,直到得到和给定服务名相同时的 pid

bool findPidByName(const std::string &servername, int &pid)
{
    struct dirent *ptr;
    FILE *fp;
    char buf[BUF_SIZE];
    char filepath[MAX_PATH];
    char cur_task_name[MAX_PATH];

    DIR *dir = opendir("/proc");
    if (nullptr != dir)
    {
        while ((ptr = readdir(dir)) != nullptr)
        {
            if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0))
                continue;

            if (DT_DIR != ptr->d_type)
                continue;

            sprintf(filepath, "/proc/%s/status", ptr->d_name); 
            fp = fopen(filepath, "r");
            if (nullptr != fp)
            {
                if (fgets(buf, BUF_SIZE - 1, fp) == nullptr)
                {
                    fclose(fp);
                    continue;
                }

                sscanf(buf, "%*s%s", cur_task_name);
                if (cur_task_name == servername)
                {
                    pid = atoi(ptr->d_name);
                    fclose(fp);
                    closedir(dir);
                    return true;
                }
                fclose(fp);
            }
        }
        closedir(dir);
    }
    return false;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会偷懒的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值