以编程方式检索OS X命令行应用程序的绝对路径

Ben*_*ack 20 c unix macos

在Linux上,应用程序可以通过查询轻松获得其绝对路径/proc/self/exe.在FreeBSD上,它更复杂,因为你必须建立一个sysctl调用:

int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char buf[1024];
size_t cb = sizeof(buf);
sysctl(mib, 4, buf, &cb, NULL, 0);
Run Code Online (Sandbox Code Playgroud)

但它仍然是完全可行的.然而,我找不到在OS X上为命令行应用程序确定这一点的方法.如果您是在应用程序包中运行[[NSBundle mainBundle] bundlePath],则可以通过运行来确定它,但由于命令行应用程序不在捆绑包中,因此无效.

(注意:咨询argv[0]不是一个合理的答案,因为,如果从符号链接启动,argv[0]将是那个符号链接 - 不是所谓的可执行文件的最终路径.argv[0]如果一个哑的应用程序使用一个exec()调用而忘记正确初始化argv ,也可能会失败 我在野外见过的.)

mar*_*k4o 52

该函数_NSGetExecutablePath将返回可执行文件的完整路径(GUI或不是GUI).该路径可能包含符号链接," .."等,但该realpath功能可用于在需要时清理它们.有关man 3 dyld更多信息,请参阅

char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) == 0)
    printf("executable path is %s\n", path);
else
    printf("buffer too small; need size %u\n", size);
Run Code Online (Sandbox Code Playgroud)

此函数的秘诀在于Darwin内核envp在创建进程时立即将可执行路径放在进程堆栈之后.动态链接编辑器dyld在初始化时抓取它并保持指向它的指针.此函数使用该指针.

  • 返回的路径是否以 null 结尾? (2认同)
  • 任何人都有手册页的更新链接? (2认同)
  • `#include <sys/syslimits.h>` `char path[PATH_MAX+1];` // 会更好 (2认同)

Ale*_*nov 28

我相信有更优雅的解决方案,它实际上适用于任何PID,并且还直接返回绝对路径:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <libproc.h>

int main (int argc, char* argv[])
{
    int ret;
    pid_t pid; 
    char pathbuf[PROC_PIDPATHINFO_MAXSIZE];

    pid = getpid();
    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;
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!但有一件事,使用OS X 10.8.5,如果没有,这对我不起作用:#include <unistd.h> (3认同)