此问题已在此处有答案:
Finding current executable's path without /proc/self/exe(15个回答)
7年前关闭。
C/C++中有没有一种方法可以找到当前执行程序的位置(完整路径)?
(The argv[0]
的问题是它没有给予完整的路径。
此问题已在此处有答案:
Finding current executable's path without /proc/self/exe(15个回答)
7年前关闭。
C/C++中有没有一种方法可以找到当前执行程序的位置(完整路径)?
(The argv[0]
的问题是它没有给予完整的路径。
9条答案
按热度按时间wpx232ag1#
总结如下:
/proc
真正直接和可靠的方法是:readlink("/proc/self/exe", buf, bufsize)
(Linux)readlink("/proc/curproc/file", buf, bufsize)
(FreeBSD)readlink("/proc/self/path/a.out", buf, bufsize)
(Solaris)/proc
的Unix上(即如果上述失败):$PATH
中搜索可执行文件argv[0]
的目录。之后,检查可执行文件是否实际上不是符号链接可能是合理的。如果是,则相对于符号链接目录解析它。
这一步在/proc方法中不是必需的(至少对于Linux是这样)。proc符号链接直接指向可执行文件。
请注意,正确设置
argv[0]
取决于调用进程。在大多数情况下,这是正确的,但是有时候调用进程不能被信任(例如:setuid可执行文件)。GetModuleFileName(NULL, buf, bufsize)
lfapxunr2#
如果您使用的是Windows,请使用GetModuleFileName()函数。
hl0ma9xz3#
请注意,下面的注解仅适用于unix。
对这个问题的迂腐的回答是,在所有情况下都没有一种通用的方法来正确回答这个问题。正如您所发现的,argv [0]可以被父进程设置为任何值,因此不需要与程序的实际名称或其在文件系统中的位置有任何关系。
然而,以下启发式通常有效:
1.如果argv [0]是绝对路径,则假定这是可执行文件的完整路径。
1.如果argv [0]是一个相对路径,即它包含一个
/
,使用getcwd()确定当前工作目录,然后将argv [0]附加到它。1.如果argv [0]是一个普通单词,搜索$PATH查找argv [0],并将argv [0]附加到您找到它的任何目录中。
请注意,所有这些都可以通过调用相关程序的进程来规避。最后,您可以使用特定于Linux的技术,例如emg-2中提到的技术。在其他操作系统上可能有等效的技术。
即使假设上面的步骤给了你一个有效的路径名,你仍然可能没有你实际想要的路径名(因为我怀疑你实际想要做的是在某处找到一个配置文件)。硬链接的存在意味着您可能会遇到以下情况:
现在,上面的方法(我怀疑包括/proc/$pid/exe)将给出
/some/where/else/foo
作为程序的真实路径。而且,事实上,这是一个真正的程序路径,只是不是你想要的。请注意,符号链接不会出现这个问题,符号链接在实践中比硬链接更常见。尽管这种方法在原则上不可靠,但在实践中对大多数目的来说都足够有效。
toe950274#
实际上不是答案,只是一个要记住的注解。
正如我们所看到的,在Linux和Unix中查找运行可执行文件的位置是相当棘手的,而且是平台特定的。在做那件事之前应该三思而后行。
如果你需要你的可执行文件位置来发现一些配置或资源文件,也许你应该遵循Unix在系统中放置文件的方式:将配置文件放到
/etc
或/usr/local/etc
或当前用户的主目录中,/usr/share
是放置资源文件的好地方。vsnjm48y5#
在许多POSIX系统中,您可以检查位于/proc/PID/exe下的simlink。几个例子:
kx5bkwkv6#
请记住,在Unix系统上,二进制文件可能在启动后就被删除了。它在Unix上是完全法律的和安全的。最后我检查了Windows将不允许您删除正在运行的二进制文件。
/proc/self/exe仍然是可读的,但它实际上不是一个有效的符号链接。会是...奇怪。
83qze16e7#
在Mac OS X上,使用
_NSGetExecutablePath
。参见
man 3 dyld
和this answer来回答类似的问题。2hh7jdfx8#
对于Linux,你可以在一个名为binreloc的漂亮库中找到
/proc/self/exe
的工作方式,你可以在以下位置找到这个库:e4yzc0pl9#
我会的
1.使用dirname()函数:http://linux.die.net/man/3/dirname
1.使用getcwd()获取当前目录
这样,您将以整洁完整的形式获得目录,而不是./或../bin/。
如果保存和恢复当前目录对程序很重要,那么可能需要保存和恢复当前目录。