Linux 无法访问 argv[0],如何获取程序名称?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4031672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Without access to argv[0], how do I get the program name?
提问by B?ови?
I know the program name is passed as the first argument, and next simple example will print it to the standard output :
我知道程序名称作为第一个参数传递,下一个简单的例子将它打印到标准输出:
#include <iostream>
int main ( int argc, char *argv[] )
{
std::cout<<argv[0]<<std::endl;
}
Is there a function to get the program name?
是否有获取程序名称的函数?
EDIT
编辑
I am starting the program from the shell, and the above code will always print the program name (I am using fedora 9, but I am sure it works in other distros).
我从 shell 启动程序,上面的代码将始终打印程序名称(我使用的是 Fedora 9,但我确定它在其他发行版中也能工作)。
I have found that /proc/self/ directory might contain what I am looking for, but I couldn't find what exactly in that directory.
我发现 /proc/self/ 目录可能包含我正在寻找的内容,但我无法在该目录中找到确切的内容。
采纳答案by Fred Foo
No, there is no such function. Linux stores the program name in __progname
, but that's not a public interface. In case you want to use this for warnings/error messages, use the err(3)
functions.
不,没有这样的功能。Linux 将程序名称存储在 中__progname
,但这不是公共接口。如果您想将其用于警告/错误消息,请使用err(3)
函数。
If you want the full path of the running program, call readlink
on /proc/self/exe
:
如果你想运行的程序的完整路径,调用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;
}
(I believe __progname
is set to the basename of argv[0]
. Check out the glibc sources to be sure.)
(我相信__progname
设置为 的基本名称argv[0]
。请查看 glibc 源以确保。)
回答by ereOn
This is not guaranteed.
这不能保证。
Usually, argv[0]
holds the executable name but one can call your executable using execve
and set it to something else.
通常,argv[0]
保存可执行文件的名称,但可以使用调用您的可执行文件execve
并将其设置为其他名称。
In a word: don't rely on this.
总之一句话:不要依赖这个。
回答by paxdiablo
No, it depends entirelyon what the parent program puts in there.
不,这完全取决于父程序在那里放置的内容。
The exec
family of functions allow the executable name to be totally different to the argument passed in, and this is supported by the ISO C standard.
该exec
系列函数允许可执行文件名是传入的参数完全不同,这是由ISO C标准的支持。
If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment.
如果argc的值大于零,则argv[0]指向的字符串代表程序名;如果宿主环境中的程序名称不可用,则 argv[0][0] 应为空字符。
So no, it's only the program name if the name is available. And the section before that states:
所以不,如果名称可用,它只是程序名称。之前的部分指出:
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-definedvalues by the host environment prior to program startup.
如果 argc 的值大于零,数组成员 argv[0] 到 argv[argc-1] 应包含指向字符串的指针,这些字符串在程序启动之前由主机环境赋予实现定义的值。
(my italics).
(我的斜体)。
So, even their values are not dictated by the standard, it's up to the implementation entirely. This means that the program name can be empty if the host environment doesn't provide it, and anything else if the host environment does provide it.
因此,即使它们的值也不是由标准决定的,这完全取决于实现。这意味着如果宿主环境不提供程序名称,则程序名称可以为空,如果宿主环境提供,则可以为其他任何内容。
However, implementation-defined has a specific meaning in the ISO standards - the implementation mustdocument how it works. So even UNIX, which can put anything it likes into argv[0]
with the exec
family of calls, has to (and does) document it.
但是,实现定义在 ISO 标准中具有特定含义 - 实现必须记录其工作方式。因此,即使UNIX,它可以把任何东西它喜欢到argv[0]
与exec
家人通话的,有(并执行)文件就可以了。
Similarly (thanks to Chubsdad), C++03 states:
同样(感谢 Chubsdad),C++03 声明:
"If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to the initial characters of null-terminated multibyte strings (NTMBSs) (17.3.2.1.3.2) and argv[0] shall be the pointer to the initial character of a NTMBS that represents the name used to invoke the program or "".
“如果 argc 非零,这些参数应在 argv[0] 到 argv[argc-1] 中作为指向空终止多字节字符串 (NTMBSs) (17.3.2.1.3.2) 和 argv[0] 的初始字符的指针提供是指向 NTMBS 的初始字符的指针,该字符表示用于调用程序的名称或“”。
So, even there, argv[0] may not contain anything and, even if it does, "represents the name" is a very vague requirement. It doesn't have to be the full pathname of the executable or even contain the command used to invoke it
因此,即使在那里, argv[0] 也可能不包含任何内容,即使包含,“代表名称”也是一个非常模糊的要求。它不必是可执行文件的完整路径名,甚至不必包含用于调用它的命令
Another way to do it under Linux is with the proc
filesystem. I think /proc/self/exe
is a link to the executable file.
在 Linux 下执行此操作的另一种方法是使用proc
文件系统。我认为/proc/self/exe
是可执行文件的链接。
Wikipedia has an entry for the procfs
filesystem with lots of goodies.
维基百科有一个关于procfs
文件系统的条目,里面有很多好东西。
回答by Eugene Smith
You can determine the pid of your process using getpid() and then inspect the contents of /proc/[pid number] using standard I/O tools.
您可以使用 getpid() 确定进程的 pid,然后使用标准 I/O 工具检查 /proc/[pid number] 的内容。
回答by Steve-o
If you use GLib you can use the function g_get_prgname()
. On Win32 it calls GetModuleFileNameW()
, on everything else it appears to return NULL though.
如果您使用 GLib,您可以使用该功能g_get_prgname()
。在 Win32 上,它调用GetModuleFileNameW()
,但在其他所有内容上它似乎都返回 NULL。
回答by Sauron
GLIBC-specific solution:
GLIBC 特定的解决方案:
#include <errno.h>
...
fprintf(stderr, "Program name is %s\n", program_invocation_name);
From man invocation_name
:
来自man invocation_name
:
program_invocation_name
contains the name that was used to invoke the calling program. This is the same as the value ofargv[0]
inmain()
, with the difference that the scope ofprogram_invocation_name
is global.
program_invocation_short_name
contains the basename component of name that was used to invoke the calling program. That is, it is the same value asprogram_invocation_name
, with all text up to and including the final slash (/), if any, removed.
program_invocation_name
包含用于调用调用程序的名称。这与argv[0]
in的值相同main()
,区别在于范围program_invocation_name
是全局的。
program_invocation_short_name
包含用于调用调用程序的 name 的 basename 组件。也就是说,它与 的值相同program_invocation_name
,但删除了直到并包括最后一个斜杠 (/) 的所有文本(如果有)。