在Linux中获取主目录

Ale*_*x F 63 c c++ linux

我需要一种方法来获取在Linux上运行的C++程序中的用户主目录.如果相同的代码在Unix上运行,那就太好了.我不想使用HOME环境值.

AFAIK,root主目录是/ root.在我的程序由root用户运行的情况下,可以在此目录中创建一些文件/文件夹吗?

R S*_*hko 89

您需要getuid获取当前用户的用户ID,然后getpwuid获取该用户的密码条目(包括主目录):

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

struct passwd *pw = getpwuid(getuid());

const char *homedir = pw->pw_dir;
Run Code Online (Sandbox Code Playgroud)

注意:如果您在线程应用程序中需要它,那么您将需要使用它getpwuid_r.

  • 请注意,`getpwuid()`手册页有这样的警告:*想要确定其用户主目录的应用程序应该检查`HOME`的值(而不是值`getpwuid(getuid()) - > pw_dir` )因为这允许用户在登录会话期间修改他们的"主目录"的概念.* (45认同)
  • 我首先检查getenv("HOME")然后检查getpwuid() (21认同)
  • 这不是原始问题的好答案。这是在`/etc/passwd` 中设置的shell 起始目录,它可能是也可能不是用户的(活动)主目录。这是有用的信息,但`getenv` 是正确的答案。 (2认同)

jos*_*sch 67

您应首先检查$HOME环境变量,如果不存在,请使用getpwuid.

#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

const char *homedir;

if ((homedir = getenv("HOME")) == NULL) {
    homedir = getpwuid(getuid())->pw_dir;
}
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您希望主目录将配置或缓存数据存储为您编写并希望分发给用户的程序的一部分,则应考虑遵循XDG基本目录规范.例如,如果要为应用程序创建配置目录,则应首先$XDG_CONFIG_HOME使用getenv如上所示进行检查,如果未设置该变量,则仅回退到上面的代码.

如果你需要多线程安全,你应该使用getpwuid_r而不是getpwuid这样(来自getpwnam(3)手册页):

struct passwd pwd;
struct passwd *result;
char *buf;
size_t bufsize;
int s;
bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (bufsize == -1)
    bufsize = 0x4000; // = all zeroes with the 14th bit set (1 << 14)
buf = malloc(bufsize);
if (buf == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
}
s = getpwuid_r(getuid(), &pwd, buf, bufsize, &result);
if (result == NULL) {
    if (s == 0)
        printf("Not found\n");
    else {
        errno = s;
        perror("getpwnam_r");
    }
    exit(EXIT_FAILURE);
}
char *homedir = result.pw_dir;
Run Code Online (Sandbox Code Playgroud)