An open community 
of Macintosh users,
for Macintosh users.

FineTunedMac Dashboard widget now available! Download Here

Previous Thread
Next Thread
Print Thread
tell me Lion didn't break $USER ?
#18593 10/19/11 07:13 PM
Joined: Aug 2009
OP Offline

Joined: Aug 2009
it appears that as of Lion, $USER is the user's LONG username, not their SHORT/unix name. This blows up so many things here it's not funny. (accessing a user's directory services records for starters)

There appears to be no shell variable for the short name? No, I can't rely on ${HOME##*/} since their home folder can be different than their short name.


I work for the Department of Redundancy Department
Re: tell me Lion didn't break $USER ?
Virtual1 #18598 10/19/11 08:51 PM
Joined: Sep 2009
Offline

Joined: Sep 2009
for a while now the (bash?) man page has mentioned that $USER will be deprecated, and that we should use $LOGNAME instead.

no Lion here, so i can' t test that.

--

besides the $LOGNAME variable, a few command substitutions which work (some better than others, depending on circumstances) are:

$(id -un)

$(whoami)

$(logname)

$(stat -f %Su /dev/console)

$(dscl . -read ~ name |awk '{print $2}')


[^ my preferred choices in blue.]

FWIW, the whoami man page recommends using id instead... and the logname man page claims that "The logname utility explicitly ignores the LOGNAME and USER environment variables, because the environment cannot be trusted." smile

Last edited by Hal Itosis; 10/19/11 09:15 PM.
Re: tell me Lion didn't break $USER ?
Virtual1 #18609 10/20/11 12:31 AM
Joined: Aug 2009
Offline

Joined: Aug 2009
Hmmm. I can't reproduce that on 10.7.2:


[dmackler@Sleek:~ 2000]$ uname -a
Darwin Sleek 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64
[dmackler@Sleek:~ 2001]$ echo $USER
dmackler


What do you have in your .bashrc and .profile?

Re: tell me Lion didn't break $USER ?
Hal Itosis #18610 10/20/11 01:43 AM
Joined: Aug 2009
Likes: 15
Online

Joined: Aug 2009
Likes: 15
Originally Posted By: V1
it appears that as of Lion, $USER is the user's LONG username, not their SHORT/unix name.

Originally Posted By: Hal
for a while now the (bash?) man page has mentioned that $USER will be deprecated, and that we should use $LOGNAME instead.

So V1's "LONG username" and your "LOGNAME" are the same thing?


The new Great Equalizer is the SEND button.

In Memory of Harv: Those who can make you believe absurdities can make you commit atrocities. ~Voltaire
Re: tell me Lion didn't break $USER ?
artie505 #18618 10/20/11 05:36 PM
Joined: Aug 2009
OP Offline

Joined: Aug 2009
Either I'm losing my mind, there's a grand conspiracy to cause the former, or I have very bad luck in selecting test machines. My script displayed a very odd behavior as a result of the "issue", and after coming back to it to test further, not only is $USER back to the short name, but the script is running fine in its original form. Maybe directory services, bash, etc just went wiggy and needed a reboot. idunno


I work for the Department of Redundancy Department
Re: tell me Lion didn't break $USER ?
artie505 #18619 10/20/11 05:39 PM
Joined: Sep 2009
Offline

Joined: Sep 2009
Originally Posted By: artie505
Originally Posted By: V1
it appears that as of Lion, $USER is the user's LONG username, not their SHORT/unix name.

Originally Posted By: Hal
for a while now the (bash?) man page has mentioned that $USER will be deprecated, and that we should use $LOGNAME instead.

So V1's "LONG username" and your "LOGNAME" are the same thing?

No.

V1's "LONG" = full name (first and last). And his capitalization of that word was for emphasis, denoting excitement.

My LOGNAME = login name (which is typically one string sans spaces, corresponding to what we call the shortname). As a shell environmental variable, it is defined with uppercase letters (i wasn't shouting).

oy vey.



@
Virtual1: whazzup my brizzle?

Re: tell me Lion didn't break $USER ?
Hal Itosis #18625 10/20/11 06:52 PM
Joined: Aug 2009
Likes: 15
Online

Joined: Aug 2009
Likes: 15
Thanks.

That was a bit confusing.


The new Great Equalizer is the SEND button.

In Memory of Harv: Those who can make you believe absurdities can make you commit atrocities. ~Voltaire
Re: tell me Lion didn't break $USER ?
Virtual1 #18630 10/21/11 01:41 AM
Joined: Sep 2009
Offline

Joined: Sep 2009
Originally Posted By: Virtual1
Either I'm losing my mind, there's a grand conspiracy to cause the former, or I have very bad luck in selecting test machines. My script displayed a very odd behavior as a result of the "issue", and after coming back to it to test further, not only is $USER back to the short name, but the script is running fine in its original form. Maybe directory services, bash, etc just went wiggy and needed a reboot. idunno

$USER only gets set initially for login shells. And it can be reassigned anytime (either by us deliberately, or by a faulty line in a script). Also, if we spinoff a subshell (e.g., by just executing /bin/bash), then that new shell's environment will inherit whatever "$USER" is at the time... because /usr/bin/login doesn't get called in that case.

So if you were seeing anything other than what you'd expect, then somehow $USER must have been reassigned somewhere along the line.

--

Oh, and i found the page which talks about deprecating $USER...

$ man environ |grep -E '(LOGNAME|USER)'

Code:
     LOGNAME    The login name of the user.
     USER       Deprecated synonym of LOGNAME (for backwards compatibility).

Last edited by Hal Itosis; 10/21/11 01:51 AM.
Re: tell me Lion didn't break $USER ?
Hal Itosis #18655 10/22/11 08:04 PM
Joined: Aug 2009
Offline

Joined: Aug 2009
Originally Posted By: Hal Itosis
$(id -un)

$(stat -f %Su /dev/console)

$(dscl . -read ~ name |awk '{print $2}')


[^ my preferred choices in blue.]

The first two aren't equivalent.
$(id -un), which is my favorite, tells you who YOU are.
$(stat -f%Su /dev/console) tells you who's logged into the GUI.
They're not the same. (Think ssh. Think su or sudo.) Either may be better, depending on which answer you want, but they can give different answers.

Which, come to think of it, is probably what you meant by "depending on circumstances".

The third form depends on the notion that a user's home folder will always be of the form /Users/$LOGNAME. That's an unwise assumption.

In the meantime, I'll try to get into the habit of using $LOGNAME rather than $USER, now that I know the latter is deprecated. In point of fact, I rarely use either, because I've run into situations where $USER isn't defined (and I never knew about $LOGNAME). $(id -un) always works.

In a similar vein, I don't trust $TMPDIR. (For example, it's not set when you ssh into a Leopard or Snow Leopard system.) I replace its first occurrence with ${TMPDIR:=$(getconf DARWIN_USER_TEMP_DIR)}, but even that doesn't work when you ssh to Tiger. (For Tiger, use TMPDIR=/var/tmp/folders.$(id -u)/-TMP-/, but you may have to create the folder.) It's already correct when you ssh to Lion.

Re: tell me Lion didn't break $USER ?
ganbustein #18656 10/22/11 09:02 PM
Joined: Aug 2009
Offline

Joined: Aug 2009
Addendum:

$USER and $LOGNAME are not interchangeable.

$USER tells you who you are now.
$LOGNAME tells you who you were when you started this login session.

For example, if you run a script as root, and the script executes su peon to temporarily drop privilege, you get USER=peon, but LOGNAME=root.

Adding a -l flag to the su command doesn't help. The new shell runs as a login shell (polluting the environment with all the stuff from peon's login scripts), but leaves $LOGNAME undefined. (The missing value can be retrieved: write it as: ${LOGNAME:=$(id -p | awk '/^login/ {print $2}')} .)

In the meantime, write your scripts as if the difference between $USER and $LOGNAME might matter, and use the one corresponding to your current needs.

Re: tell me Lion didn't break $USER ?
ganbustein #18657 10/22/11 09:47 PM
Joined: Aug 2009
Offline

Joined: Aug 2009
Originally Posted By: ganbustein
(The missing value can be retrieved: write it as: ${LOGNAME:=$(id -p | awk '/^login/ {print $2}')} .)

Silly me! $(logname), as suggested by Hal, is already a simpler way to do this.

In the meantime, I've been thinking about the deprecation warning, and realized that what's being deprecated is the use of USER as a synonym for LOGNAME.

That's not a shoe waiting to be dropped. It's already happened. USER is already no longer a synonym for LOGNAME, and we needn't be afraid to use it to access the name of the current user, if that's what we want, even in new scripts. (That's assuming you aren't worried that someone may have mucked with your environment. If you are, use $(id -un) instead, as a safer but slower alternative.)

Re: tell me Lion didn't break $USER ?
ganbustein #18660 10/23/11 03:22 AM
Joined: Sep 2009
Offline

Joined: Sep 2009
Quite a while ago, I wrote a script called whu which iterates through (most of) those possibilities. That way i could easily call it from various "states of being" to find out what results the differing methods would produce under some particular condition. E.g., if testing a login or logout hook, one can call whu and direct its output to a file on the desktop... and then check that file later, to see what was what. [i always meant to test it with Fast User Switching too, but never got around to it.]

Code:
#!/bin/bash -
# script to compare various methods of determining the current user's identity
IFS=$' \t\n'
declare -x PATH=/bin:/usr/bin
UZER=`defaults read /Library/Preferences/com.apple.loginwindow lastUserName`
printf '\n %s %15s%15s\n' IDENTITY EFFECTIVE REAL
printf ' `id -un` %15s%15s <-- user \n' "$(id -u -n)" "$(id -r -u -n)"
printf ' `id -gn` %15s%15s <-- group\n' "$(id -g -n)" "$(id -r -g -n)"
echo ' _________________________________________________'
echo
echo USER/UID:
echo ' `whoami`               =' `whoami`
echo ' `logname`              =' `logname`
echo ' $LOGNAME               =' $LOGNAME
echo ' $USER                  =' $USER
echo ' $UID                   =' $UID
echo
echo ' $SUDO_UID              =' $SUDO_UID
echo ' ${SUDO_UID:-$UID}      =' ${SUDO_UID:-$UID}
printf ' $(basename ~)          = %s\n' "$(basename ~)"
echo ' ${HOME##/*/}           =' ${HOME##/*/}
echo ' _________________________________________________'
printf "\n \$(dscl . -read ~ name|\n   awk '{ print \$2 }' ) = "
dscl . -read ~ name |awk '{ print $2 }'
printf '\n $(stat -f %%Su /dev/console) = '
stat -f %Su /dev/console
printf '\ndefaults read /Library/Preferences/\
com.apple.loginwindow lastUserName = %s\n' "$UZER"
echo
exit 0




Example output (when called with sudo, just to make it somewhat interesting):

$ sudo whu

Code:

 IDENTITY       EFFECTIVE           REAL
 `id -un`            root           root <-- user 
 `id -gn`           wheel          wheel <-- group
 _________________________________________________

USER/UID:
 `whoami`               = root
 `logname`              = halito
 $LOGNAME               = root
 $USER                  = root
 $UID                   = 0

 $SUDO_UID              = 501
 ${SUDO_UID:-$UID}      = 501
 $(basename ~)          = halito
 ${HOME##/*/}           = halito
 _________________________________________________

 $(dscl . -read ~ name|
   awk '{ print $2 }' ) = halito

 $(stat -f %Su /dev/console) = halito

defaults read /Library/Preferences/\
com.apple.loginwindow lastUserName = halito



Note the discrepancy between `logname` and $LOGNAME

Last edited by Hal Itosis; 10/23/11 03:32 AM.

Moderated by  alternaut, dkmarsh, joemikeb 

Link Copied to Clipboard
Powered by UBB.threads™ PHP Forum Software 7.7.4
(Release build 20200307)
Responsive Width:

PHP: 7.4.33 Page Time: 0.025s Queries: 38 (0.017s) Memory: 0.6348 MB (Peak: 0.7397 MB) Data Comp: Zlib Server Time: 2024-04-26 06:27:11 UTC
Valid HTML 5 and Valid CSS