8

I am curious why can't we switch to a user's home director with either

$ cd ~"$USER"

or

$ cd ~${USER}
2
  • 4
    Because it's so much simpler just to type "cd"?
    – jamesqf
    May 17, 2018 at 18:11
  • 7
    @jamesqf, we all know what can be done.. the question here is about what can not be done and why? May 17, 2018 at 18:52

5 Answers 5

20

That very much depends on the shell and the order the expansions are done in those shells.

~$user expands to the home directory of the user whose name is stored in $user in csh (where that ~user feature comes from), AT&T ksh, zsh, fish.

Note however these variations:

$ u=daemon/xxx csh -c 'echo ~$u'
/usr/sbin/xxx  # same in zsh/fish
$ u=daemon/xxx ksh93 -c 'echo ~$u'
~daemon/xxx

$ u=daemon/xxx csh -c 'echo ~"$u"'
Unknown user: daemon/xxx.
$ u=daemon/xxx zsh -c 'echo ~"$u"'
/usr/sbin/x  # same in fish

$ u=" daemon" csh -c 'echo ~$u'
/home/stephane daemon
$ u=" daemon" zsh -c 'echo ~$u'
~ daemon  # same in ksh/fish

$ u="/daemon"  csh -c 'echo ~$u'
/home/stephane/daemon  # same in zsh
$ u="/daemon"  fish -c 'echo ~$u'
~/daemon  # same in ksh

It expands to the home directory of the user named literally $user in bash (provided that user exists, which is very unlikely of course).

And to neither in pdksh, dash, yash, presumably because they don't consider $user to be a valid user name.

2
  • Can you please suggest me where can I learn more about expansion in various shells. May 17, 2018 at 14:30
  • 6
    @Neo_Returns, their respective manuals, and when that's not clearly documented, with trial and error and the source code for those where it's available... May 17, 2018 at 14:37
10

Tilde expansion is a separate step in the processing of the command line. It happens just before variable expansion.

If the tilde is followed by something other than a slash, it will expand to the home directory of the user whose name is following the tilde, as in, for example, ~otheruser. Since $USER is not expanded at that point and since it's unlikely to correspond to a valid username, the tilde is left unexpanded.

$USER is likely to be the username of the current user, so your expression could probably be replaced by just ~.

0
6

As other answers have pointed out the behavior depends on which order the shell does ~ and $ expansions and whether it will even do both for the same word.

The behavior you were looking for is possible to achieve in bash by a very small change to your command. Simply prefix the command with eval.

eval "cd ~$USER"

will change to the home directory of the user given by the username in the variable USER, provided $USER doesn't contain characters special to the shell (if there's a remote chance that it might, you should not pass it as argument to eval as that would be dangerous) or / characters and that there's an entry for that user in the system's user database.

3

An alternative way to look up a variable user's home directory, if you are using one of the shells where tilde expansion happens before variable expansion, is with getent. This tool exists on at least Linux, Solaris, and FreeBSD; I'm not sure how universal it is.

$ USER=bloggs
$ getent passwd "$USER" | cut -d: -f6
/home/b/bloggs

As with tilde expansion, this might not give you the same thing that su - $USER -c 'echo $HOME' would print if you had the privileges to do that.

1
  • 1
    See also perl -le 'print((getpwnam shift)[7])' -- "$USER" as potentially slightly more portable. May 18, 2018 at 10:37
-2

Since the OP insists on an answer, here it is.

The behavior of those commands (and many other things) depends on the particular shell you happen to be using. Unless you specifiy which particular shell you use, it is probably not possible to give a simple answer.

As a matter of fact, if you use tcsh, as I do, both of the expressions in the OP's question (as it is written as I write this - I take no responsibility for future edits!) work perfectly well. I don't know what other shells will do, since I don't use them. So perhaps the OP doesn't know quite as much about what can be done as s/he thinks :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.