在Linux上,应用程序可以通过查询/ proc / self / exe轻松获取绝对路径。在FreeBSD上,由于您必须建立一个sysctl调用,所以它更多的涉及到: int mib[4];mib[0] = CTL_KERN;mib[1] = KERN_PROC;mib[2] = KERN
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);
但它仍然是完全可行的。然而,我找不到一种在OS X上确定命令行应用程序的方法。如果您从应用程序包中运行,则可以通过运行[[NSBundle mainBundle] bundlePath]来确定它,但是由于命令行应用程序不在捆绑中,因此这无济于事。
(注意:咨询argv [0]不是一个合理的答案,因为如果从符号链接启动,argv [0]将是符号链接 – 不是被称为可执行文件的最终路径。argv [0]也可以说如果愚蠢的应用程序使用exec()调用,并忘记正确初始化argv,我在野外看到过)
功能_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);
该功能的秘诀在于,当创建该进程时,Darwin内核会在envp数组之后立即将可执行路径放在进程堆栈上。动态链接编辑器dyld在初始化时抓住它,并保留一个指针。此函数使用该指针。