Windows与Linux GCC argv 值

可能重复:
获取可执行文件的path

我使用MinGW,gcc 4.4.3在Windows上进行编程。 当我使用这样的主要function:

int main(int argc, char* argv[]){ cout << "path is " << argv[0] << endl; } 

在Windows上,我得到了这样的完整path:“C:/ dev / stuff / bin / Test”。 当我在Linux上运行相同的应用程序时,我得到了一些相对path:“bin / Test”。 这是打破我的申请! 任何想法如何确保两个系统上的path是绝对的?

不,没有。 在Linux上的大多数shell下, argv[0]包含用户键入的运行二进制文件的内容。 这允许二进制文件根据用户输入的内容做不同的事情。

例如,具有多个不同命令行命令的程序可以安装一次二进制文件,然后将各种不同的命令硬连接到同一个二进制文件。 例如,在我的系统上:

 $ ls -l / usr / bin / git *
 -rwxr-xr-x 109根轮2500640 16 May 18:44 / usr / bin / git
 -rwxr-xr-x 2根轮子121453 16 May 18:43 / usr / bin / git-cvsserver
 -rwxr-xr-x 109根轮2500640 16 May 18:44 / usr / bin / git-receive-pack
 -rwxr-xr-x 2根轮子1021264 16 May 18:44 / usr / bin / git-shell
 -rwxr-xr-x 109根轮2500640 16 May 18:44 / usr / bin / git-upload-archive
 -rwxr-xr-x 2根轮子1042560 16五月18:44 / usr / bin / git-upload-pack
 -rwxr-xr-x 1个根轮323897 16 May 18:43 / usr / bin / gitk

注意这些文件中有些文件的大小完全相同。 更多的调查显示:

 $ stat / usr / bin / git
 234881026 459240 -rwxr-xr-x 109根轮0 2500640“Oct 29 08:51:50 2011”“”May 16 18:44:05 2011“”Jul 26 20:28:29 2011“”May May 18:44: 05 2011“4096 4888 0 / usr / bin / git
 $ stat / usr / bin / git-receive-pack 
 234881026 459240 -rwxr-xr-x 109根轮0 2500640“Oct 29 08:51:50 2011”“”May 16 18:44:05 2011“”Jul 26 20:28:29 2011“”May May 18:44: 05 2011“4096 4888 0 / usr / bin / git-receive-pack

inode号(459240)是相同的,所以这两个链接到磁盘上的同一个文件。 运行时,二进制使用argv[0]的内容来确定执行哪个函数。 你可以在Git的main()的代码中看到这个(有点main()

argv数组

argv[0]是一个类似于任何其他的参数:它可以是一个任意的NUL终止的字节字符串。 它可以是空字符串。 无论启动过程如何,

默认情况下,将argv[0]设置为shell用于命名程序的shell:在$PATH查找的名称,相对路径或绝对路径。 它可以是一个符号链接或一个常规文件。

要用其他值调用一个程序,用zsh(不要和其他shell)使用:

 ARGV0 = whatever_you_want some_program参数

如果您确实需要可执行文件的路径,则不能在Unix上使用命令行。

仅限Linux

在Linux上: /proc/self/exe是可执行文件的符号链接。

你可以readlink 。 您也可以直接statopen它。

重命名和软链接

一个正常的软链接是一个哑巴的字符串,并不知道它的目标(如果它存在的话)发生了什么。 但是/proc/self/exe软链接是神奇的。

在重命名的情况下,soft-but-magic-link将会重命名。 如果有几个硬链接,它将遵循所使用的特定硬链接的名称。 (因此,在Linux下不同的硬链接到相同的文件是不完全等效的。)

如果这个硬链接没有链接,我认为" (deleted)"被附加到符号链接的值。 请注意,这是一个有效的文件名,所以另一个不相关的文件可以有这个名字。

在任何情况下, 符号链接都是文件的硬链接 ,因此您可以直接statopen它。

我不认为你可以指望任何网络文件系统上的二进制文件重命名或取消链接在另一个系统,而不是可执行文件启动。

安全考虑

当你的程序使用/proc/self/exe特殊文件时,用来启动程序的文件可能被unlinkrename d。 在程序有特权的情况下(SUID或Set Capabilities),这应该被认真对待:即使用户没有对原来的“Set Something”二进制文件的写访问权限,他也许能够与他建立一个硬连接具有对同一文件系统上的目录的写入权限,所以如果正在运行的特权二进制文件,他可能会更改该名称。

在您readlink ,返回的值可能会引用另一个文件。 (当然, open readlink的结果总会有一个不可避免的竞争条件。)

像往常一样,NFS不提供与本地文件系统相同的所有保证。

没有办法确保argv[0]是绝对路径,因为它应该是用户调用程序的方式。 所以,如果在Linux命令行上通过./bin/Test调用你的程序,那么argv[0]应该完全是"./bin/Test"

这看起来像MinGW的运行时错误,如果你通过.\bin\Testargv[0]"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)也对argv[0]具有".\bin\Test"