我需要一种在Linux上运行的C ++程序中获取用户主目录的方法。如果相同的代码可以在Unix上运行,那就太好了。我不想使用HOME环境值。
AFAIK,根主目录是/ root。如果我的程序由root用户运行,可以在此目录中创建一些文件/文件夹吗?
我需要一种在Linux上运行的C ++程序中获取用户主目录的方法。如果相同的代码可以在Unix上运行,那就太好了。我不想使用HOME环境值。
AFAIK,根主目录是/ root。如果我的程序由root用户运行,可以在此目录中创建一些文件/文件夹吗?
~
由外壳而不是内核或libc实现。使用C ++编程时,您需要自己实现。
$HOME
直通车getenv("HOME")
?
Answers:
您需要getuid
获取当前用户的用户ID,然后getpwuid
获取该用户的密码条目(包括主目录):
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
struct passwd *pw = getpwuid(getuid());
const char *homedir = pw->pw_dir;
注意:如果您在线程化应用程序中需要此功能,则可以getpwuid_r
改用。
getpwuid()
手册页有以下警告:想要确定其用户主目录的应用程序应检查HOME
(而不是value getpwuid(getuid())->pw_dir
)的值,因为这允许用户在登录会话期间修改其“主目录”的概念。
/etc/passwd
,它可能是也可能不是用户的(活动)主目录。这是有用的信息,但是getenv
正确的答案。
您应该首先检查$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;
}
还要注意,如果您希望主目录将配置或缓存数据作为编写的程序的一部分并希望分发给用户,则应考虑遵循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;
getpwuid_r
。我不知道为什么该功能在语言环境中摆弄。
free(buf)
我回答我,那可能会误导人,并导致问题为时过早,free()
因为根据手册页getpwuid_r
:“ passwd结构的成员指向的字符串字段存储在缓冲区buf中大小为buflen。” 因此buf
,只要有用就保持pwd
有用。
getenv("HOME")
在Ubuntu 17.10上为我返回错误的内容。它返回应用程序的工作目录。
getpwuid()
则将使用户无法使用其他命令运行该过程$HOME
。
如果您以root用户身份运行程序,那么您将具有rwx访问此目录的权限。我想在里面创建东西很好。
~
不是吗?如cd ~
,mv some_file ~/some_file
等等