我知道程序名称作为第一个参数传递,下一个简单示例将它打印到标准输出:
#include <iostream>
int main ( int argc, char *argv[] )
{
std::cout<<argv[0]<<std::endl;
}
是否有获取程序名称的功能?
修改
我从shell启动程序,上面的代码将始终打印程序名称(我使用的是Fedora 9,但我相信它适用于其他发行版)。
我发现/ proc / self /目录可能包含我要查找的内容,但我无法找到该目录中的确切内容。
答案 0 :(得分: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;
}
(我相信__progname
设置为argv[0]
的基本名称。请查看glibc来源以确定。)
答案 1 :(得分:9)
这不能保证。
通常,argv[0]
包含可执行文件名,但可以使用execve
调用您的可执行文件并将其设置为其他名称。
总之:不要依赖于此。
答案 2 :(得分: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
文件系统的条目,有许多好东西。
答案 3 :(得分:4)
GLIBC特定解决方案:
#include <errno.h>
...
fprintf(stderr, "Program name is %s\n", program_invocation_name);
来自man invocation_name
:
program_invocation_name
包含用于调用调用程序的名称。这与argv[0]
中main()
的值相同,但program_invocation_name
的范围是全局的。
program_invocation_short_name
包含用于调用调用程序的name的basename组件。也就是说,它与program_invocation_name
的值相同,所有文本都包括最后的斜杠(/),如果有的话,删除。
答案 4 :(得分:3)
您可以使用getpid()确定进程的pid,然后使用标准I / O工具检查/ proc / [pid number]的内容。
答案 5 :(得分:2)
如果您使用GLib,则可以使用函数g_get_prgname()
。在Win32上它调用GetModuleFileNameW()
,在其他所有东西上都会返回NULL。