【发布时间】:2012-02-01 14:11:10
【问题描述】:
如何在 C 中获取进程名称?同名,在/proc/$pid/status 中。我不想解析那个文件。有没有任何程序化的方式来做到这一点?
【问题讨论】:
如何在 C 中获取进程名称?同名,在/proc/$pid/status 中。我不想解析那个文件。有没有任何程序化的方式来做到这一点?
【问题讨论】:
如果你正在使用 glibc,那么:
#define _GNU_SOURCE
#include <errno.h>
extern char *program_invocation_name;
extern char *program_invocation_short_name;
参见 program_invocation_name(3)
在大多数 Unices 下,__progname 也由 libc 定义。
唯一可移植的方式是使用argv[0]
【讨论】:
它要么由argv[0] 指向,要么您确实可以阅读/proc/self/status。或者你可以使用getenv("_"),但不确定是谁设置的以及它有多可靠。
【讨论】:
getenv("_") 似乎返回了最初由 shell 启动的进程——如果我在由make 启动的进程中调用它,我看到的是“/usr/bin/make”,而不是比我的进程名称。这意味着它可能是由 shell 设置的。
您可以使用__progname。但是它并不比argv[0] 好,因为它可能存在可移植性问题。但由于您无权访问argv[0],它可以按如下方式工作:-
extern char *__progname;
printf("\n%s", __progname);
【讨论】:
我经常使用跟随调用,
char* currentprocname = getprogname();
【讨论】:
libbsd 在 Linux 上获取它,但它不是 libc 的一部分,因为它在 FreeBSD 或 OS X 上。
查看传递给main 的argv[0] 的值。这应该是调用进程的名称。
【讨论】:
/proc/self/cmdline。
getenv("_"),虽然我不确定它有多可靠。
这是一个适用于 macOS、FreeBSD 和 Linux 的版本。
#if defined(__APPLE__) || defined(__FreeBSD__)
const char * appname = getprogname();
#elif defined(_GNU_SOURCE)
const char * appname = program_invocation_name;
#else
const char * appname = "?";
#endif
【讨论】:
如果您无法访问 main() 中的 argv[],因为您正在实现一个库,您可以查看我对类似问题 here 的回答。
它基本上归结为让您可以在 main() 之外访问 argc、argv[] 和 envp[]。 然后,正如其他人已经正确建议的那样,您可以使用 argv[0] 来检索进程名称。
【讨论】:
对于后代来说,一个更接近 C++ 并且也适用于 MSVC 的版本:
#define FMT_HEADER_ONLY
#include <fmt/format.h>
std::string get_current_process_name()
{
#if defined(__APPLE__) || defined(__FreeBSD__)
return getprogname();
#elif defined(_GNU_SOURCE)
return program_invocation_name;
#elif defined(_WIN32)
return __argv[0];
#else
return "?";
#endif
}
int main()
{
fmt::print("whatsmyname: {}\n", get_current_process_name());
return 0;
}
// msvc output:
// whatsmyname: C:\Users\<user>\source\repos\Project6\Debug\Project6.exe
【讨论】: