根据进程名字查找pid

本文介绍在Linux系统中如何通过进程名查找进程PID,反之亦然。提供了使用命令行工具的方法,并分享了一个C语言示例程序,用于演示如何编程实现这一功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Liunx中通过进程名查找进程PID可以通过 pidof [进程名] 来查找。反过来 ,相同通过PID查找进程名则没有相关命令。在linux根目录中,有一个/proc的VFS(虚拟文件系统),系统当前运行的所有进程都对应于该目录下的一个以进程PID命名的文件夹,其中存放进程运行的N多信息。其中有一个status文件,cat显示该文件, 第一行的Name即为进程名。

打开stardict程序,进程名为stardict;

shell中分别根据Pid获取进程名、根据进程名获取Pid

1)查找stardict的pid:pidof stardict

2)根据1)的pid查找进程名: grep "Name:" /proc/5884/status

应用:kill一个进程需要指定该进程的pid,所以我们需要先根据进程名找到pid,然后再kill;
killall命令则只需要给定进程名即可,应该是封装了这个过程。

C程序中实现上述过程


#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_SIZE 1024
char* getPidByName(char* task_name, char * pid)
{
DIR *dir;
struct dirent *ptr;
FILE *fp;
char filepath[50];//大小随意,能装下cmdline文件的路径即可
char cur_task_name[50];//大小随意,能装下要识别的命令行文本即可
char buf[BUF_SIZE];
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/status", ptr->d_name);//生成要读取的文件的路径
  fp = fopen(filepath, "r");//打开文件
if (NULL != fp)
{
if( fgets(buf, BUF_SIZE-1, fp)== NULL ){
fclose(fp);
continue;
}
sscanf(buf, "%*s %s", cur_task_name);


//如果文件内容满足要求则打印路径的名字(即进程的PID)
if (!strcmp(task_name, cur_task_name)){
printf("PID:  %s\n", ptr->d_name);
strcpy(pid, ptr->d_name);

}
fclose(fp);
}


}
closedir(dir);//关闭路径
}
return ptr->d_name;
}

void getNameByPid(pid_t pid, char *task_name) {
char proc_pid_path[BUF_SIZE];
char buf[BUF_SIZE];
sprintf(proc_pid_path, "/proc/%d/status", pid);
FILE* fp = fopen(proc_pid_path, "r");
if(NULL != fp){
if( fgets(buf, BUF_SIZE-1, fp)== NULL ){
fclose(fp);
}
fclose(fp);
sscanf(buf, "%*s %s", task_name);
    }
}

void main(int argc, char *argv[])
{
char task_name[50];
char *pid = (char*)calloc(10,sizeof(char));
strcpy(task_name, argv[1]);
printf("task name is %s\n", task_name);
getPidByName(task_name, pid);
printf("---pid is %s\n", pid);
sprintf(text, "/proc/%s/oom_score_adj", pid);  
fd = open(text, O_WRONLY);  
if (fd >= 0) 
{  
sprintf(text, "%d", -1000);  
write(fd, text, strlen(text));  
close(fd);  
}
sleep(15);
}



对转载内容进行了小修改http://www.jb51.net/article/45012.htm

<think>我们正在解决如何根据PID查找Linux进程的可执行文件启动路径的问题。根据提供的引用,我们可以通过几种方法实现: ### 方法1: 使用`pwdx`命令 ```bash pwdx <PID> ``` 这个命令会直接输出进程的工作目录(cwd),但注意这并不一定是可执行文件的路径,而是进程当前的工作目录。 ### 方法2: 查看`/proc`文件系统 在`/proc`文件系统中,每个进程都有一个以其PID的目录。在这个目录下,有两个符号链接特别重要: - `exe`:指向进程的可执行文件的绝对路径。 - `cwd`:指向进程的当前工作目录。 因此,我们可以通过以下命令查看可执行文件的路径: ```bash ls -l /proc/<PID>/exe ``` 或者 ```bash readlink /proc/<PID>/exe ``` ### 方法3: 使用`ps`命令 虽然`ps`命令主要用于查看进程状态,但也可以结合格式输出来获取可执行文件的路径: ```bash ps -f -p <PID> ``` 在输出中,`CMD`列可能会显示命令的路径,但注意这可能是命令而不是完整路径。更可靠的方式是使用`-o`选项指定输出字段: ```bash ps -p <PID> -o comm= # 只输出命令(不包含路径) ps -p <PID> -o cmd= # 输出完整的命令(可能包含参数) ``` 但是,`ps`命令并不能直接给出可执行文件的绝对路径。因此,更推荐使用`/proc`文件系统的方法。 ### 方法4: 使用`lsof`命令 ```bash lsof -p <PID> | grep txt ``` 在输出中,查找类型为`txt`(即可执行文件)的行,其中会显示可执行文件的路径。 ### 示例 假设我们有一个进程PID是1234,我们可以这样查找其可执行文件路径: ```bash # 方法1: 使用/proc ls -l /proc/1234/exe # 方法2: 使用readlink readlink /proc/1234/exe # 方法3: 使用lsof lsof -p 1234 | grep txt ``` ### 注意事项 1. 需要权限:如果进程属于其他用户,可能需要使用`sudo`来查看。 2. 路径解析:`/proc/PID/exe`是一个符号链接,如果可执行文件被删除,链接会显示为`(deleted)`,但此时仍然可以通过该链接读取到原始路径(如果文件被删除,则无法执行)。 3. 对于内核进程:内核进程(如kthreadd)没有可执行文件路径,因此这些方法可能不适用。 ### 完整步骤 1. 确定进程PID(可以通过`ps`、`top`、`pgrep`等命令获取)。 2. 使用上述任一方法查看可执行文件路径。 ### 代码示例(Bash函数) 我们可以编写一个简单的Bash函数来快速获取进程的可执行文件路径: ```bash get_exe_path() { if [ -z "$1" ]; then echo "Usage: get_exe_path <PID>" return 1 fi pid="$1" if [ -e "/proc/$pid/exe" ]; then readlink "/proc/$pid/exe" else echo "No such process: $pid" >&2 return 1 fi } ``` 使用方法: ```bash get_exe_path 1234 ``` ### 相关问题 1. 如何根据进程查找PID? 2. 如何查看进程的当前工作目录? 3. 如何查看进程打开的所有文件? 4. 如果进程的可执行文件被删除,如何恢复? [^1]: 引用[1]提到了通过`/proc`目录查看进程信息的方法。 [^2]: 引用[2]详细说明了`/proc/pid/exe`是一个指向可执行文件的符号链接。 [^3]: 引用[3]介绍了`/proc/PID`目录下的各个文件的作用。 [^4]: 引用[4]给出了使用`pwdx`和查看`cwd`、`exe`的实例。 [^5]: 引用[5]提到了通过`ps`和`netstat`查找进程和端口的方法。</think>### 根据PID查找Linux进程启动路径的完整指南 在Linux系统中,可以通过`/proc`文件系统获取进程的详细信息,以下是几种可靠的方法: #### 方法1:使用`/proc/PID/exe`符号链接(推荐) ```bash # 查看进程的可执行文件绝对路径 readlink /proc/<PID>/exe # 示例(PID=1234): readlink /proc/1234/exe # 输出示例:/usr/bin/python3.9 ``` #### 方法2:检查`/proc/PID/cwd`(工作目录) ```bash # 查看进程的当前工作目录 readlink /proc/<PID>/cwd # 示例: readlink /proc/1234/cwd # 输出示例:/home/user/project ``` #### 方法3:使用`pwdx`命令 ```bash # 显示进程的工作目录 pwdx <PID> # 示例: pwdx 1234 # 输出:1234: /home/user/project ``` #### 方法4:组合命令(带详细路径) ```bash # 同时显示可执行文件路径和工作目录 echo "可执行文件: $(readlink /proc/1234/exe)" echo "工作目录: $(readlink /proc/1234/cwd)" ``` #### 方法5:通过`ps`命令获取启动命令 ```bash # 查看进程的完整启动命令 ps -p <PID> -o cmd= # 示例: ps -p 1234 -o cmd= # 输出示例:/usr/bin/python3 app.py ``` ### 关键目录说明 在`/proc/<PID>/`目录中: | 文件/目录 | 作用 | |----------------|----------------------------------------------------------------------| | **exe** | 指向进程可执行文件的符号链接(绝对路径)[^2] | | **cwd** | 指向进程当前工作目录的符号链接[^3] | | cmdline | 包含进程的完整启动命令和参数 | | environ | 进程的环境变量列表 | | status | 进程状态信息(内存使用、UID等) | ### 实际应用示例 假设需要查找PID为`5678`的进程信息: ```bash # 1. 获取可执行文件路径 $ readlink /proc/5678/exe /opt/app/server # 2. 获取工作目录 $ readlink /proc/5678/cwd /var/log/app # 3. 查看启动命令 $ ps -p 5678 -o cmd= /opt/app/server --port=8080 ``` ### 注意事项 1. 需要读取权限:普通用户只能查看自己的进程,查看系统进程需要`sudo` 2. 僵尸进程:如果进程已结束(僵尸状态),`/proc`中的信息可能不完整 3. 符号链接解析:当可执行文件被删除时,`exe`链接会显示`(deleted)`后缀 4. 容器环境:在Docker等容器中,显示的是容器内的路径,而非宿主机路径 ### 自动化脚本示例 ```bash #!/bin/bash get_process_info() { pid=$1 echo "进程ID: $pid" echo "可执行文件: $(readlink /proc/$pid/exe 2>/dev/null || echo '不可访问')" echo "工作目录: $(readlink /proc/$pid/cwd 2>/dev/null || echo '不可访问')" echo "启动命令: $(cat /proc/$pid/cmdline 2>/dev/null | tr '\0' ' ' || echo '不可访问')" } # 使用示例 get_process_info 1234 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值