What is a ~ (tilde) when used as a prefix to a path?
What is ~foo
Quote from bash manual (with added emphasis):
If a word begins with an unquoted tilde character (`~'), all of the characters preceding the first unquoted slash (or all characters, if there is no unquoted slash) are considered a tilde-prefix.If none of the characters in the tilde-prefix are quoted, the characters in the tilde-prefix following the tilde are treated as a possible login name.
~foo
expands to foo
user's home directory exactly as specified in /etc/passwd
. Note, that this can include system usernames; it doesn't necessarily mean human users or that they can actually log in locally ( they can log in via SSH keys for instance).
In fact, as noted in the comments, bash
will use getpwnam
function. That function itself is specified by POSIX standard, hence should exist on most Unix-like systems, including macOS X. This function isn't limited to /etc/passwd
only and searches other databases, such as LDAP and NIS. Particular excerpt from bash
source code, tilde.c
file, starting at line 394:
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
#if defined (HAVE_GETPWNAM)
user_entry = getpwnam (username);
#else
user_entry = 0;
Practical example
Below you can see tests with system usernames on my system. Pay attention to corresponding passwd
entry and result of ls ~username
$ grep '_apt' /etc/passwd
_apt:x:104:65534::/nonexistent:/bin/false
$ ls ~_apt
ls: cannot access '/nonexistent': No such file or directory
$ grep '^lp' /etc/passwd
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
$ ls ~lp
ls: cannot access '/var/spool/lpd': No such file or directory
Even if for instance _apt
account is locked as suggested by output of passwd -S apt
it is still showing up as possible login name:
_apt L 11/29/2017 0 99999 7 -1
Please note: This is not macOS specific feature, but rather shell-specific feature.
In summary of why you are seeing something for ~foo/bar
, it is because you have a user named foo
on the system with a folder named bar
in their home directory.
See this solution in another community that explains why (tilde) ~
is more than just "home directory".
If you have a user named bin
on your system, then you can list the contents of bin's home directory by the command:
ls ~bin
One other thing you can try is to use tab completion after typing the following at a prompt (don't carriage return, just use the tab key):
ls -lah ~
tab
to see the list of users' home directories that ~
will expand to if you continue to. Example (truncated) output of tab completion of ls -lah ~
tab
$ ls -lah ~ [tab]
~antman/ ~games/
~bin/ ~mail/