无法访问argv [0],如何获取程序名称?

BЈо*_*вић 10 c c++ linux command-line-arguments

我知道程序名称作为第一个参数传递,下一个简单示例将它打印到标准输出:

#include <iostream>
int main ( int argc, char *argv[] )
{
  std::cout<<argv[0]<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

是否有获取程序名称的功能?

编辑

我从shell启动程序,上面的代码将始终打印程序名称(我使用Fedora 9,但我相信它适用于其他发行版).

我发现/ proc/self /目录可能包含我要查找的内容,但我无法找到该目录中的确切内容.

Fre*_*Foo 19

不,没有这样的功能.Linux存储程序名称__progname,但这不是公共接口.如果要将其用于警告/错误消息,请使用这些err(3)功能.

如果你想运行的程序的完整路径,调用readlink/proc/self/exe:

char *program_path()
{
    char *path = malloc(PATH_MAX);
    if (path != NULL) {
        if (readlink("/proc/self/exe", path, PATH_MAX) == -1) {
            free(path);
            path = NULL;
        }
    }
    return path;
}
Run Code Online (Sandbox Code Playgroud)

(我相信__progname设置为基本名称argv[0].确定glibc来源.)

  • 你不应该使用`__progname`,因为它没有文档,仅供`err(3)`函数内部使用.(如果你想作弊,用`extern const char*__ progname声明它;`但实际上,你不想作弊.) (2认同)

ere*_*eOn 9

这不保证.

通常,argv[0]保存可执行文件名,但可以使用execve它来调用您的可执行文件并将其设置为其他名称.

总之一句话:不要依赖于此.

  • @Chubsdad:ereOn刚刚指出这可能不是真的.所以不,它并不总是程序的名称. (3认同)
  • @Chubsdad:如果你知道写自己的答案.如果你只是想,那就去查一下或者等一下知道回答的人吧.目前你错了(和愚蠢的羊跟你一起投票你的评论). (3认同)
  • 这比那更糟糕.在Linux上使用bash,这个参数是面向用户的:bash -c'exec -a"argv [0]中的漂亮程序名"./executable' (3认同)
  • argv [0]总是我认为的程序的名称. (2认同)

Sau*_*ron 9

GLIBC 特定的解决方案:

#include <errno.h>
...
fprintf(stderr, "Program name is %s\n", program_invocation_name);
Run Code Online (Sandbox Code Playgroud)

来自man invocation_name

program_invocation_name包含用于调用调用程序的名称。这与argv[0]in的值相同main(),区别在于范围program_invocation_name是全局的。

program_invocation_short_name包含用于调用调用程序的 name 的 basename 组件。也就是说,它与 的值相同 program_invocation_name,但删除了直到并包括最后一个斜杠 (/) 的所有文本(如果有)。

  • 在我的环境中,没有“man incall_name”。相反,我必须参考[`man program_in Vocation_name`](http://man7.org/linux/man-pages/man3/program_in Vocation_name.3.html)。 (5认同)

pax*_*blo 6

不,这完全取决于父计划放在那里的内容.

exec系列函数允许可执行文件名是传入的参数完全不同,这是由ISO C标准的支持.

如果argc的值大于零,则argv [0]指向的字符串表示程序名称; 如果程序名不能从主机环境获得,则argv [0] [0]应为空字符.

所以不,如果名称可用,它只是程序名称.之前的部分说明:

如果argc的值大于零,则数组成员argv [0]到argv [argc-1]包含指向字符串的指针,在程序启动之前由主机环境给出实现定义的值.

(我的斜体).

因此,即使它们的价值不是由标准决定的,也完全取决于实施.这意味着如果主机环境不提供程序名称,则程序名称可以为空,如果主机环境确实提供程序名称,则程序名称可以为空.

但是,实现定义在ISO标准中具有特定含义 - 实现必须记录其工作原理.因此,即使UNIX,它可以把任何东西它喜欢到argv[0]exec家人通话的,有(并执行)文件就可以了.

同样(感谢Chubsdad),C++ 03指出:

"如果argc非零,则这些参数应在argv [0]中通过argv [argc-1]提供,作为指向以null结尾的多字节字符串(NTMBS)(17.3.2.1.3.2)和argv [0]的初始字符的指针.是指向NTMBS的初始字符的指针,该NTMBS表示用于调用程序或""的名称.

因此,即使在那里,argv [0]也可能不包含任何东西,即使它确实如此,"代表名称"也是一个非常含糊的要求.它不必是可执行文件的完整路径名,甚至不包含用于调用它的命令


在Linux下执行此操作的另一种方法是使用proc文件系统.我认为/proc/self/exe是可执行文件的链接.

维基百科有一个procfs文件系统的条目,有很多好东西.