谁设置 $USER 和 $USERNAME 环境变量?

tsh*_*ang 45 environment-variables

另外,这些变量是否总是与当前登录的用户名匹配(它们在我的 Debian 系统上匹配)?我可以假设它们在其他 Unix(-like) 系统中可用吗?

我也很好奇为什么人们会使用whoami而不是仅仅读取这些变量中的任何一个。

poi*_*ige 35

这是登录

Linux login(1)手册页说:

对于价值$ HOME$ USER$ SHELL$ PATH$ LOGNAME$ MAIL根据在密码输入相应的字段设置。

FreeBSD login(1)手册页说:

登录实用程序进入信息到环境中(参见 ENVIRON(7) )指定该用户的主目录(HOME),命令解释器(SHELL),搜索路径(PATH),终端类型(TERM)和用户名(二者LOGNAME和USER) .

NetBSD的OpenBSD系统OS X的手册页说同样的话。

这是来自 util-linux 登录的源代码

setenv("HOME", pwd->pw_dir, 0); /* legal to override */
setenv("USER", pwd->pw_name, 1);
setenv("SHELL", pwd->pw_shell, 1);
/* ... */
setenv("LOGNAME", pwd->pw_name, 1);
Run Code Online (Sandbox Code Playgroud)

这是FreeBSD 登录的源代码

(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
Run Code Online (Sandbox Code Playgroud)

  • 在我的 Fedora 16 机器上,我设置了 `USER` 和 `USERNAME`,你的命令只返回 `LOGNAME`。 (2认同)
  • 请注意,Linux 只是一个内核,它没有“登录”命令。使用 Linux 作为内核的操作系统可以自由使用他们喜欢的任何实现。例如,基于 Debian 的系统倾向于使用 shadow-utils,而不是 util-linux。 (2认同)

Sté*_*las 13

没有规则。一些 shell 喜欢tcshzsh设置$LOGNAME. zsh$USER

它可能由一些让您登录的东西设置login(如getty在终端上登录时调用,有时由其他东西如in.rlogind)、cronsusudosshdrshd、 图形登录管理器设置,也可能不设置。

如果有登录,根据我的经验,$USER通常会设置(但在登录会话中更改用户 ID(通过 setuid 命令)后可能不会更新。POSIX 要求$LOGNAME在登录时设置(和cron)。

为了可移植地获取登录名,最好使用该logname命令(如果没有任何登录,它可能不返回任何内容)。要获取用户 ID,请使用id -u. 获取与当前有效用户 ID 对应的一个用户名:id -un。要获取所有这些信息(大多数情况下,每个用户 ID 只有一个用户名,但不能保证):

perl -le 'while ($n = getpwent()) {print $n if getpwnam($n) == $>}'
Run Code Online (Sandbox Code Playgroud)

尽管这可能不适用于无法枚举用户数据库的系统(例如有时会发生在网络用户数据库中)。


nea*_*mcb 6

您可能希望在这里依赖POSIX标准,因为在某个时间点,您可能不仅会关心用户登录(由login程序管理),还会关心cron作业等。

因此,您应该知道 POSIX 需要$LOGNAME但不需要$USER. 例如$USER,正如Keith Thompson回答中指出的那样,可能不是由 cron 设置的,该回答还引用了一些历史,说明这与 System-V 与 BSD 的历史有何关系:

...至少在我的系统(Ubuntu 14.04)上,没有为 cron 作业设置 $USER 环境变量。相反,您可以使用 $LOGNAME,它是 cron 作业环境的一部分。

根据environ(7)手册页(输入man environ 来阅读它),$USER 被BSD 派生程序使用,$LOGNAME 被System-V 派生程序使用。


Jes*_*olm 5

如果您想使用环境变量(而不是whoamiorgetpwentgetpwnam)并且不确定它们在所有 *NIX 系统上是否始终以相同的方式设置,请在 bash 中尝试:

THIS_USER=${USER:-${USERNAME:-${LOGNAME}}}
echo ${THIS_USER}
Run Code Online (Sandbox Code Playgroud)

如果它仍然是空的,那么你就处于一个相当深奥的系统中。;)