我知道可以使用ps
命令获得一个进程的PID
,但如何找到该进程的完整路径?
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 上测试过。
$> which \
ps -o comm= -p 81233` => ./ft_minishell2`,我的意思是,它不是绝对路径,而是相对路径。不知道这是否是问题最初的想法。这是Mavericks操作系统。 - conradkleinespelps
的答案都不够充分,因为在MacOS上,如果进程是使用相对路径或仅使用文件名启动的,然后在PATH
中查找,那么ps
命令将无法显示完整路径。只有当进程使用其完整路径启动时,ps
命令才能显示可执行文件的完整路径。lsof
命令来显示在MacOS上运行的进程的完整路径名,无论它们是如何启动的,如下所示:lsof -d txt
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
这将为您提供所有正在运行的名为python
或Python
的进程的完整路径,而不考虑大小写。
lsof
列出的是打开的文件,而不是代表进程的文件。请参见例如 https://en.wikipedia.org/wiki/Procfs。 - Bill Horvathlsof
命令绝对提供了这个信息。我们不会在这里列出所有打开的文件,关键在于-d txt
开关,它仅列出每个进程已映射到内存中的“文本段”(也称为“可执行代码”),直接显示了正在运行的进程来自哪个可执行文件的路径。P.S. procfs在Mac OS上不存在。 - grnch一个更加便携和现代化的@tomis's answer版本:
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 是您想要检查的进程名称。
osxfuse
吗?这个仓库文件系统包含了多个令人兴奋和有用的文件系统源代码,例如 sshfs、procfs、AccessibilityFS 等等,供你浏览、编译和构建。 - ymn