Linux C已知進程名字得到其PID號

最近需要實現一個功能,即在一個Linux C程序中,已知其他進程的名字,需要獲得該進程的PID,經過一番上網搜索,找到兩種可行的方法:

1.通過popen創建一個管道,執行shell命令並得到返回結果

2.通過搜索/proc文件夾下的文件內容,得到進程PID(順帶演示一下Linux C中如何讀取一個文件夾中的內容)

爲了方便進行測試,首先隨便寫了一段代碼如下:

#include<stdio.h>
void main()
{
    char c;
    scanf("%c", &c);
}

將代碼編譯爲二進制文件test,並使用./test運行,由於該代碼中由於有scanf函數存在,會一直阻塞,下面就可以運行其它程序來查詢這個進程的PID了。

一、通過popen的方法

我們知道,在shell下可以通過下述命令來得到進程test的PID:

ps -e | grep 'test' | awk '{print $1}'

(注:這個命令中,名字中含有test字樣的進程都會被掃描到,如果只針對名字恰好爲test的進程,則需要修改這個命令)

那麼在Linux C程序中,只要將這個命令移到shell環境中執行一下,並讀取其執行結果即可。在Linux C程序中執行shell命令可以通過popen函數,該函數會返回一個文件指針,可以像操作文件一樣對這個返回的指針進行操作。關於popen函數的細節,網上一搜一大把,這裏就不說了,直接上代碼:

#include<stdio.h>
#include<string.h>
void main()
{
    FILE *fp = popen("ps -e | grep \'test\' | awk \'{print $1}\'", "r");//打開管道,執行shell 命令
    char buffer[10] = {0};
    while (NULL != fgets(buffer, 10, fp)) //逐行讀取執行結果並打印
    {
        printf("PID:  %s", buffer);
    }
    pclose(fp); //關閉返回的文件指針,注意不是用fclose噢
}

二、通過搜索/proc文件夾下的內容獲取進程PID

在系統的/proc文件夾下,保存有系統當前所有進程的信息,比如一個進程的PID爲10000,那麼/proc下會有一個名字爲10000的文件夾,其中包含有該進程的幾乎所有信息:其中/proc/10000/cmdline文件中保存了啓動該進程時使用的命令行。

由於剛纔的進程是通過./test運行的,因此只要遍歷/proc下的文件夾,如果發現某個文件夾中的cmdline文件內容爲./test,則該文件夾的名字即爲進程的PID,代碼如下:

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

void main()
{
    DIR *dir;
    struct dirent *ptr;
    FILE *fp;
    char filepath[50];//大小隨意,能裝下cmdline文件的路徑即可
    char filetext[50];//大小隨意,能裝下要識別的命令行文本即可

    dir = opendir("/proc"); //打開路徑
    if (NULL != dir)
    {
        while ((ptr = readdir(dir)) != NULL) //循環讀取路徑下的每一個文件/文件夾
        {

            //如果讀取到的是"."或者".."則跳過,讀取到的不是文件夾名字也跳過
            if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) continue;
            if (DT_DIR != ptr->d_type) continue;
           
            sprintf(filepath, "/proc/%s/cmdline", ptr->d_name);//生成要讀取的文件的路徑
            fp = fopen(filepath, "r");//打開文件

            if (NULL != fp)
            {
                fread(filetext, 1, 50, fp);//讀取文件
                filetext[49] = '\0';//給讀出的內容加上字符串結束符

                //如果文件內容滿足要求則打印路徑的名字(即進程的PID)
                if (filetext == strstr(filetext, "./test")) printf("PID:  %s\n", ptr->d_name);
                fclose(fp);
            }
           
        }

        closedir(dir);//關閉路徑
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章