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/