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; }