It's login.
The Linux login(1) man page says:
The value for $HOME, $USER, $SHELL, $PATH, $LOGNAME, and
$MAIL are set according to the appropriate fields in the password entry.
The FreeBSD login(1) man page says:
The login utility enters information into the environment (see
environ(7)) specifying the user's home directory (HOME), command
interpreter (SHELL), search path (PATH), terminal type (TERM) and user name
(both LOGNAME and USER).
The NetBSD, OpenBSD and OS X man pages say the same thing.
Here's the source code from the util-linux login:
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);
Here's the source code from the FreeBSD login:
(void)setenv("LOGNAME", username, 1);
(void)setenv("USER", username, 1);
(void)setenv("PATH", rootlogin ? _PATH_STDPATH : _PATH_DEFPATH, 0);
man
page,whoami
reports the name associated with your effective user ID. Which means it will return something different if you're usingsudo
or running a setuid executable. If you havesudo
set up, trysudo whoami
for example.USER
andUSERNAME
are ordinary environment variables, which means that, if you want, you can set them to arbitrary values. Just typeUSER=xyz
. In other words, even if those variables exist, there is no guarantee that their values match the currently logged-in username.guarantee
, I meant by default (i.e. assuming user did not change them).sudo whoami
andsudo echo $USER
sudo echo $USER
, the shell expands$USER
, then callssudo
. So of course it doesn't produce the same output aswhoami
. Likesudo whoami
,sudo sh -c 'echo $USER'
does (typically) outputroot
. Regarding your comment aboutwhoami
using the EUID, note thatsudo whoami
would outputroot
even ifwhoami
used the UID.sudo
sets both EUID and UID for the command it runs (except in the very unusual situation that you explicitly configure it to behave otherwise). Comparesudo id -u
tosudo id -ru
.