如何在OS X系统中获取进程的完整路径?

25

我知道可以使用ps命令获得一个进程的PID,但如何找到该进程的完整路径?


http://superuser.com/questions/103309/how-can-i-know-the-absolute-path-of-a-running-process - Iswanto San
可能是从pid获取应用程序的真实路径?的重复问题。 - talha2k
5个回答

22

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/


1
我已经修改了这段代码,使其接受一个PID作为参数,并打印出该进程可执行文件的绝对路径:https://gist.github.com/bukzor-sentryio/f74da9b1799c2f239476941774cf5552 - bukzor

14

一种解决方案是使用哪个:

which `ps -o comm= -p $PID`

这里 $PID 是你想要检查的进程的 pid。在 OS X 10.8.2 上测试过。


2
也在10.7.5上测试过了...太棒了。 - Floris
1
有时似乎会返回相对路径。这是我进行的测试:$> which \ps -o comm= -p 81233` => ./ft_minishell2`,我的意思是,它不是绝对路径,而是相对路径。不知道这是否是问题最初的想法。这是Mavericks操作系统。 - conradkleinespel
15
如果您在不同的位置拥有同名的可执行文件,特别是那些不在您的路径中的文件,则这可能不准确。 "which" 命令会在您的 PATH 环境变量中搜索给定的可执行文件,但这并不一定是在进程列表中出现的那个文件。@conradk 之所以说它是“相对的”,是因为它位于您当前的目录中。 - DustinB
有没有办法在绝对路径结果中不换行?(已在10.12.6上测试) - Michael
1
在macOS 11.4 Big Sur中似乎运行得非常好! - Altimac
显示剩余3条评论

2
所有涉及ps的答案都不够充分,因为在MacOS上,如果进程是使用相对路径或仅使用文件名启动的,然后在PATH中查找,那么ps命令将无法显示完整路径。只有当进程使用其完整路径启动时,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的进程,而不会返回其他内容。

最后一个问题是,苹果有时喜欢将与MacOS捆绑在一起的可执行文件的名称大写。

例如,与MacOS捆绑的Python可执行文件实际上被命名为Python(大写P),即使您从命令行启动它时使用的是小写字母python

为了解决这个问题,-c参数还允许在正则表达式后面添加i标志进行不区分大小写匹配,如下所示:

lsof -a -d txt -c /^python$/i

这将为您提供所有正在运行的名为pythonPython的进程的完整路径,而不考虑大小写。


这并没有回答楼主的问题。lsof 列出的是打开的文件,而不是代表进程的文件。请参见例如 https://en.wikipedia.org/wiki/Procfs。 - Bill Horvath
@BillHorvath,你在MacOS上尝试过上面的命令吗?OP要求运行进程的可执行文件的完整路径,上述lsof命令绝对提供了这个信息。我们不会在这里列出所有打开的文件,关键在于-d txt开关,它仅列出每个进程已映射到内存中的“文本段”(也称为“可执行代码”),直接显示了正在运行的进程来自哪个可执行文件的路径。P.S. procfs在Mac OS上不存在。 - grnch

-2

一个更加便携和现代化的@tomis's answer版本:

command -v "$(ps -o comm= -p $PID)"

command -v 取代了 which 并且更加便携。

反引号被 $(cmds) 取代。

还有另一种选择,它依赖于 GNU CoreUtils 中的 realpath

realpath /proc/$PID/exe

-8

试试这个:

sudo ls -l /proc/$(ps -e | grep $PROCESS_NAME | awk '{print $1}')/exe

$PROCESS_NAME 是您想要检查的进程名称。


你听说过 osxfuse 吗?这个仓库文件系统包含了多个令人兴奋和有用的文件系统源代码,例如 sshfs、procfs、AccessibilityFS 等等,供你浏览、编译和构建。 - ymn
2
我听说过这个(并使用它),但它不是本地的...许多用户没有安装它。 - tomis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接