~ is $HOME, but sometimes?
~
is an alias for $HOME
provided by a number of shells, but $HOME
is more universal. $HOME
actually asks the shell to insert (substitute) the environmental variable HOME here. There are quite a number of different environmental variable that can be substituted, try running env
for a list. Note that ~
is not always recognized when it's not at the beginning of a word. Try these two commands for comparison:
ls /~
ls /$HOME
The first gets passed to the ls executable as /~
which then tries to look at a file called ~
in the root directory, the second expands $HOME
and becomes //home/user
which is then passed to the ls executable as a command-line argument. All POSIX systems (POSIX is the standard for how UNIX and Linux systems operate) allow multiple slashes to be treated the same as one slash so //home/user
is the same as saying /home/user
. ~username
is a shortcut for telling the shell to look up username in the passwd file and return their home directory. There is no equivalent environment variable. All of these substitution are done by the shell and are supported by most of them, but only environment variables like $HOME
are guaranteed to be supported by all shells. Also, cd
is actually a built-in command. It's a special directive that tells the shell itself to change directories. It's not like other shell built-ins that can be implemented as a separate executable like echo
is because it's used to change a fundamental attribute of the shell process. echo
is merely a shell built-in for performance reasons, but in the good old days of UNIX, was only available as it's own executable /bin/echo
.
~foo
means 'the home directory of user foo'.
This isn't done by the kernel, it's interpreted by the shell. Whenever the shell sees ~foo
as an argument, it transparently replaces it with the home directory of user foo
and passes that in its place. So when you run cd ~tandu
, the shell is actually running cd /home/tandu
.
~
followed by a username expands to that user's home directory.