从PID获取过程的名称
1. 概述
Linux 操作系统为每个进程生成一个PID 。在这个快速教程中,让我们探索如何通过给定的 PID 获取进程名称。
2. 问题介绍
像往常一样,让我们通过一个例子来理解这个问题。
首先,让我们创建一个简单的 shell 脚本来模拟一个长时间运行的进程:
$ cat long-running.sh
#!/bin/bash
echo "PID of $0: $$"
echo "Parameter: $1"
watch -n 300 date > /dev/null
正如我们所见,我们首先通过读取特殊变量*$$ 来打印当前脚本的 PID 。然后,我们告诉watch 命令每 300 秒执行一次date*命令并丢弃输出。
这样我们在启动脚本的时候就可以知道它的PID。此外,它作为一个“长期运行”的进程运行:
$ ./long-running.sh PARAM
PID of ./long-running.sh: 407203
parameter: PARAM
现在,假设我们只知道这个 PID,我们想知道哪个进程正在使用这个 PID 运行。
当然,我们预期的结果是long-running.sh脚本。接下来,让我们看看如何找到该进程。
3. 使用ps命令
ps 命令是在 Linux 命令行中检查当前进程状态的标准工具。
此外,我们可以将*-p PID选项传递给ps*命令以仅获取给定进程的信息,例如:
$ ps -p 407203
PID TTY TIME CMD
407203 pts/3 00:00:00 long-running.sh
如上面的输出所示,我们在 CMD 列中看到了预期的进程名称。我们也可以调整ps命令的*-o*选项,让 ps只输出需要的信息。
例如,我们可以将“ -o comm ”传递给ps命令以仅获取程序的名称:
$ ps -p 407203 -o comm
COMMAND
long-running.sh
如果我们想知道用于启动给定进程的整个命令行,我们可以将“ -o command ”传递给ps:
$ ps -p 407203 -o command
COMMAND
/bin/bash ./long-running.sh PARAM
如输出所示,这一次ps命令报告了完整的命令,包括用于启动进程的参数。
有时,我们想抑制列标题,例如上面输出中的“ COMMAND ”,以便我们可以轻松地将结果传递给其他程序进行进一步处理。
为了抑制ps输出的标题,我们可以简单地在-o ColumnName*选项 之后添加“=”字符*:
$ ps -p 407203 -o command=
/bin/bash ./long-running.sh PARAM
4. 读取*/proc/PID*目录下的文件
/proc目录存在于所有 Linux 发行版上。该目录是一个虚拟文件系统。** /proc目录包含有关进程的**详细信息和其他系统信息,例如内核、内存使用情况、CPU 数据和配置参数。操作系统在启动时挂载*/proc*。
每个进程在/proc*目录下都有一个以 PID 命名*的子目录。比如我们要查看进程407203的信息,可以进入*/proc/407203目录。每个/proc/PID*目录下都有许多“文件” 。这些文件包含有关该过程的详细信息:
$ ls /proc/407203
arch_status cwd@ maps pagemap stat
attr/ environ mem personality statm
...
exe@ ...
cmdline io ns/ sessionid timers
comm ...
**我们可以读取三个文件来获取进程的名称或命令行:comm、exe和cmdline。**接下来,让我们看看他们的行动。
要获取进程的程序名,我们可以读取comm文件:
$ cat /proc/407203/comm
long-running.sh
exe文件是一个符号链接。它链接到真正的命令文件以启动该过程:
$ ls -l /proc/407203/exe
lrwxrwxrwx 1 kent kent 0 Apr 26 09:20 /proc/407203/exe -> /usr/bin/bash
由于我们的进程是一个shell脚本,它总是由shell启动,所以exe文件只会链接到shell命令,在这种情况下是*/usr/bin/bash*。但是,如果我们的进程是由常规程序启动的,则exe文件将指向可执行文件:
$ ls -l /proc/437301/exe
lrwxrwxrwx 1 kent kent 0 Apr 26 09:17 /proc/437301/exe -> /usr/bin/vim
上面的例子显示了一个vim进程。 但是,如果我们想知道启动进程的完整命令及其参数,我们可以查看cmdline文件:
$ cat /proc/407203/cmdline
/bin/bash./long-running.shPARAM
如上面的输出所示,shell 命令、脚本名称和脚本参数被打印出来,但是它们没有分隔符连接在一起。 实际上,输出由空字符 分隔。如果我们将*-A选项(显示全部)传递给cat*命令,我们可以看到它们:
$ cat -A /proc/407203/cmdline
/bin/bash^@./long-running.sh^@PARAM^@
这一次,我们可以看到空字符表示为’ ^@ ‘。 我们可以使用tr 命令重新格式化输出。例如,我们可以用空格替换所有空字符:
$ cat /proc/407203/cmdline | tr '\0' ' '
/bin/bash ./long-running.sh PARAM