可能重复:
Get path of executable
我使用MinGW,gcc 4.4.3在Windows上编程。当我使用这样的主函数时:
int main(int argc, char* argv[]){
cout << "path is " << argv[0] << endl;
}
在Windows上,我得到一个完整的路径:“C:/ dev / stuff / bin / Test”。但是,当我在Linux上运行相同的应用程序时,我会得到某种相对路径:“bin / Test”。这打破了我的申请!关于如何确保路径在两个系统上都是绝对的任何想法?
答案 0 :(得分:9)
不,没有。在Linux上的大多数shell下,argv[0]
包含用户键入以运行二进制文件的内容。这允许二进制文件根据用户输入的内容执行不同的操作。
例如,具有多个不同命令行命令的程序可以安装二进制文件一次,然后将各种不同的命令硬链接到同一个二进制文件。例如,在我的系统上:
$ ls -l /usr/bin/git* -rwxr-xr-x 109 root wheel 2500640 16 May 18:44 /usr/bin/git -rwxr-xr-x 2 root wheel 121453 16 May 18:43 /usr/bin/git-cvsserver -rwxr-xr-x 109 root wheel 2500640 16 May 18:44 /usr/bin/git-receive-pack -rwxr-xr-x 2 root wheel 1021264 16 May 18:44 /usr/bin/git-shell -rwxr-xr-x 109 root wheel 2500640 16 May 18:44 /usr/bin/git-upload-archive -rwxr-xr-x 2 root wheel 1042560 16 May 18:44 /usr/bin/git-upload-pack -rwxr-xr-x 1 root wheel 323897 16 May 18:43 /usr/bin/gitk
请注意其中一些文件的大小完全相同。更多调查显示:
$ stat /usr/bin/git 234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44:05 2011" 4096 4888 0 /usr/bin/git $ stat /usr/bin/git-receive-pack 234881026 459240 -rwxr-xr-x 109 root wheel 0 2500640 "Oct 29 08:51:50 2011" "May 16 18:44:05 2011" "Jul 26 20:28:29 2011" "May 16 18:44:05 2011" 4096 4888 0 /usr/bin/git-receive-pack
inode编号(459240)是相同的,因此它们是指向磁盘上同一文件的两个链接。运行时,二进制文件使用argv[0]
的内容来确定要执行的函数。您可以在code for Git's main()
。
答案 1 :(得分:4)
argv[0]
是一个与其他参数类似的参数:它可以是任意NUL终止的字节字符串。它可以是空字符串。无论启动过程是什么,它都是。
默认情况下,设置argv[0]
的shell用于命名程序的名称:在$PATH
中查找的名称,相对路径或绝对路径。它可以是符号链接或常规文件。
要使用zsh(带有其他shell的dunno)调用具有其他值的程序,请使用:
ARGV0=whatever_you_want some_program arguments
如果您确实需要可执行文件的路径,则无法在Unix上使用命令行。
在Linux上:/proc/self/exe
是指向可执行文件的符号链接。
你可以readlink
。您也可以直接stat
或open
。
正常的软链接是一个愚蠢的字符串,并且不知道它的目标会发生什么(如果它存在的话)。但/proc/self/exe
软链接很神奇。
在重命名的情况下,soft-but-magic-link将遵循重命名。如果有多个硬链接,它将遵循所使用的特定硬链接的名称。 (因此,在Linux下,同一文件的不同硬链接并不完全相同。)
如果取消链接此硬链接,我认为" (deleted)"
会附加到符号链接的值。请注意,这是一个有效的文件名,因此另一个不相关的文件可以具有该名称。
无论如何,符号链接是指向文件的硬链接,因此您可以直接stat
或open
。
如果二进制文件在另一个系统上重命名或取消链接,而不是启动可执行文件的系统,我认为你不能指望网络文件系统上的任何东西。
当您的程序使用/proc/self/exe
特殊文件时,用于启动程序的文件可能会unlink
或rename
d。如果程序具有特权(SUID或设置功能),则应该认真对待:即使用户没有对原始“Set Something”二进制文件的写访问权限,他也许能够建立一个硬链接,如果他具有对同一文件系统上的目录的写访问权限,因此如果正在运行的特权二进制文件,他可以更改名称。
到readlink
时,返回的值可能会引用另一个文件。 (当然,open
的结果readlink
始终存在不可避免的竞争条件。)
与往常一样,NFS不提供本地文件系统所具有的所有相同保证。
答案 2 :(得分:3)
无法确保argv[0]
是绝对路径,因为它应该是用户调用程序的确切方式。因此,如果在Linux命令行上通过./bin/Test
调用您的程序,那么argv[0]
应该是"./bin/Test"
。
如果从命令提示符.\bin\Test
通过argv[0]
调用程序时{38},这似乎是MinGW运行时中的错误。"C:/dev/stuff/bin/Test"
。使用最新的MinGW(gcc版本4.5.2),通过.\bin\Test
调用二进制文件意味着argv[0]
为".\bin\Test"
。通过.\bin\Test
调用的Microsoft Visual C ++构建的二进制文件(cl版本16.00.40219.01)对".\bin\Test"
也有argv[0]
。