linuxisperfect 2014-05-08
Linux查询pid有多种方式,可通过遍历/proc目录下进程运行信息及shell ps命令
1. 遍历/proc目录
Linux下每个运行的进程都会在/proc目录下建立该进程pid目录,/proc/pid 目录下有 status, cmdline等描述进程运行参数,状态等信息. 运行可能没有命令行参数,cmdline文件可能为空. 我们选择 status 文件,比较 status 中 Name 字段即可

// 根据进程名称查找pid
pid_t GetPidByName(const char *pName)
{
DIR *pdir = NULL;
struct dirent *pde = NULL;
FILE *pf = NULL;
char buff[128];
pid_t pid;
char szName[128];
// 遍历/proc目录下所有pid目录
pdir = opendir("/proc");
if (!pdir)
{
perror("open /proc fail.\n");
return -1;
}
while ((pde = readdir(pdir)))
{
if ((pde->d_name[0] < '0')|| (pde->d_name[0] > '9'))
{
continue;
}
// 读取 /proc/$pid/status文件
sprintf(buff, "/proc/%s/status", pde->d_name);
pf = fopen(buff, "r");
if (pf)
{
fgets(buff,sizeof(buff),pf);
fclose(pf);
sscanf(buff,"%*s %s",szName); // 跳过Name:字段,获取进程名称
pid=atoi(pde->d_name);
if(strcmp(szName,pName)==0)
{
closedir(pdir);
return pid;
}
}
}
closedir(pdir);
return 0;
}二. ps 命令


通过上述截图发现,如果进程名称过长,会被截断,这种情况下无法通过status匹配进程名称,而ps命令却完美解决上述问题,可以通过管道接收shell执行结果
int FindPidByName(const char *pName)
{
int szPid=-1;
char szProQuery[256];
sprintf(szProQuery,"ps -ef|grep '%s'|grep -v 'grep'|awk '{print $2}'",pName); // 打开管道,执行shell命令
FILE *fp=popen(szProQuery,"r");
char szBuff[10];
while(fgets(szBuff,10,fp)!=NULL) // 逐行读取执行结果
{
szPid=atoi(szBuff);
break;
}
pclose(fp); // 关闭管道指针,不是fclose()很容易混淆
return szPid;
}