我知道我可以使用
PID
获取进程的 ps
,但是如何找到该进程的完整路径?
OS X 有 libproc 库,可用于收集不同的 处理信息。为了找到给定的绝对路径 PID,可以使用以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libproc.h>
int main (int argc, char* argv[])
{
pid_t pid; int ret;
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
if ( argc > 1 ) {
pid = (pid_t) atoi(argv[1]);
ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
if ( ret <= 0 ) {
fprintf(stderr, "PID %d: proc_pidpath ();\n", pid);
fprintf(stderr, " %s\n", strerror(errno));
} else {
printf("proc %d: %s\n", pid, pathbuf);
}
}
return 0;
}
编译和运行的示例(上面的代码存储在pathfind.c中,32291是我试图查找路径信息的进程的pid):
$ cc pathfind.c -o pathfind
$ ./pathfind 32291
proc 32291: /some/path/your-binary-app
参考这篇博文: http://astojanov.wordpress.com/2011/11/16/mac-os-x-resolve-absolute-path-using-process-pid/
可以使用一种解决方案:
which `ps -o comm= -p $PID`
其中 $PID 是您要检查的进程的 pid。在 OS X 10.8.2 上测试。
所有涉及
ps
的答案都是不够的,因为 MacOS 上的 ps
命令只能显示可执行文件的完整路径(如果使用其完整路径启动)。如果使用相对路径或仅使用随后在 PATH
中查找的文件名启动进程,则 ps
命令将不会显示完整路径。
lsof
命令可用于显示MacOS上正在运行的进程的完整路径名,无论它们是如何启动的,如下所示:
lsof -d txt
输出的最后一列显示每个可执行文件的完整路径。
如果您只想查看 PID 123 的特定进程的完整路径:
lsof -a -d txt -p 123
在这种情况下,
-a
参数很重要,可以强制指定条件的“AND”匹配。
如果您想按进程名称查看完整路径,可以使用以下命令:
lsof -a -d txt -c python
这将为您提供可执行文件名称以“python”开头的所有正在运行的进程的完整路径。这意味着您可能还会在此列表中获得“python2”和“python3”进程,这通常是您想要的。
但是,如果您想要进程名称精确匹配,
-c
命令还支持正则表达式,因此您可以使用像这样的锚定正则表达式:
lsof -a -d txt -c /^python$/
这只会为您提供名为
python
的进程,而不会提供其他任何内容。
最后一个问题是 Apple 有时喜欢将与 MacOS 捆绑在一起的可执行文件的名称大写。
例如,与 MacOS 捆绑的 Python 可执行文件实际上名为
Python
(大写 P),即使您从命令行启动它为 python
(小写 P)。
为了解决这个问题,
-c
参数还允许通过在正则表达式后附加i
标志来进行不区分大小写的匹配,如下所示:
lsof -a -d txt -c /^python$/i
这将为您提供所有名为
python
或 Python
的正在运行的进程的完整路径,无论大小写。
command -v "$(ps -o comm= -p $PID)"
command -v
取代了 which
并且更便携。
反引号替换为
$(cmds)
还有另一个依赖于 GNU CoreUtils 中的
realpath
的替代方案:
realpath /proc/$PID/exe
试试这个:
sudo ls -l /proc/$(ps -e | grep $PROCESS_NAME | awk '{print $1}')/exe
其中 $PROCESS_NAME 是您要检查的进程的名称。