35

This question already has an answer here:

Let's suppose Mary is a directory. Is the following path ~/Mary relative?

marked as duplicate by Peter Cordes, Stephen Rauch, G-Man, Satō Katsura, sebasth Oct 14 '17 at 9:46

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • Similar: Path syntax rules – Stéphane Chazelas Oct 12 '17 at 13:19
  • 1
    I would describe the "Mary" part as being relative to the (context dependent) tilde (~) part. – StephenG Oct 12 '17 at 14:33
  • As an aside, a path does not have to point to a directory so assuming Mary to be a directory in not needed for your question. – hildred Oct 12 '17 at 19:58
  • 4
    If you are related to Mary then it is a path to your relative ... – Ross Presser Oct 13 '17 at 4:41
  • 3
    @StephenG That's like saying all paths are relative… to /. – Sparhawk Oct 13 '17 at 12:18
73

No, it's not relative.

It's a full path, with ~ being an alias.

Relative paths describe a path in relation to your current directory location. However, ~/Mary is exactly the same, no matter which directory you're currently in.

Assuming you were currently logged in as Bob and also in the directory /home/Bob, then ../Mary would be an example of a relative path to /home/Mary. If you were currently in /etc/something then ~/Mary would still be /home/Bob/Mary but ../Mary would now be /etc/Mary.

Note that Bash handles ~ in particular ways, and that it doesn't always translate to $HOME.

For further reading, see

  • 9
    ../Mary in /home/Bob would not refer to /home/Bob/Mary, it would refer to /home/Mary. Perhaps you meant to write /home/Bob/something? – fNek Oct 12 '17 at 13:10
  • 21
    I would avoid calling ~ an alias; that name is already taken. Rather, it is simply a token that is part of a different shell feature, tilde expansion. Aside from ~ alone and ~user, there are also absolute and relative directory stack expressions like ~+, ~-, ~2, ~+1, ~-3, etc. – chepner Oct 12 '17 at 13:40
  • @chepner I wonder if a user can name itself 2 on the system. If yes, then ~2 wouldn't work to go to that user's Home, right? Or would it? – Cœur Oct 12 '17 at 15:52
  • 3
    @Cœur, all numeric user names would be a bad idea as several commands accept both username and userids in the same context (like find -user 0, ps -u 0...) – Stéphane Chazelas Oct 12 '17 at 16:02
  • 18
    ~/Mary is /home/youruser/Mary, ~Mary is /home/Mary. – Kroltan Oct 12 '17 at 16:47
49

If that ~/Mary is a path given to any system call (like open(),stat()...), then it's a relative path, it's the Mary entry related to the ~ directory in the current directory. So if your current directory is /tmp for instance, that will be the /tmp/~/Mary file.

However, if that ~/Mary is used unquoted in a shell (or other tool) that supports tilde expansion, then that ~ will be substituted with the content of the $HOME variable (if it's set), and as $HOME typically contains an absolute path like /home/me, ~/Mary will be expanded to /home/me/Mary, so an absolute path as well.

If you change $HOME to be a relative path (but you wouldn't want to do that), then ~/Mary would be expanded to a relative path by the shell:

$ HOME=..; echo ~/Mary
../Mary

If you change it to //foo (or if your home directory was / which used to be common for root), then the expansion of ~/Mary would be neither an absolute pathname nor a relative pathname (at least per the POSIX definitions).

With bash versions prior to 4.0, you could even do funny things like:

$ HOME='*' bash-3.2.48 -c 'cd /; echo ~/mount'
bin/mount run/mount

(that was fixed in 4.0)

More info on Unix&Linux at

  • 2
    Egads. A relative $HOME like HOME=.. is frightening. – Adam Katz Oct 12 '17 at 17:46
  • 2
    @AdamKatz, what about a wildcard $HOME like HOME='*' (see edit) ;-) – Stéphane Chazelas Oct 12 '17 at 18:21
  • 1
    Crazy values of HOME? So many things I wish I didn't know... 😱 – dhag Oct 12 '17 at 18:30
  • 3
    Looks like HOME=. works too, and you can have a little fun with HOME='~'; cd generating an error like bash: cd: ~: No such file or directory. Wow, this rabbit hole is deep... – Adam Katz Oct 12 '17 at 21:48
7

Lets get pedantic.

As others have stated, it is an alias; as such, it is strictly neither an absolute path nor a relative path. Practically, it is an absolute path as it is not relative to the working directory.

Now for the details. At an OS level, aliases are not supported, so the rule that all absolute paths start with a slash holds true, and everything else is a relative path. However, applications might not just pass the name to the kernel: special handling of :, ~ and - is common and application dependent. - is used to start options so to ensure that you are using a relative path you can prepend ./ to force relative handling in almost all cases (as far as I know the sole exception is a hostname containing a slash in some implementations of rcp or scp). Recognition of : is used in detecting urls and remote hosts for some commands and leading // also has special meaning in some cases, but all of these cases are application level issues not OS level.

Almost all shells (I know of one exception) and many Unix applications support basic tilde expansion. The two tilde expansions that are most likely to work are ~/path (where the leading tilde is replaced with the contents of the $HOME variable), and ~name/path (where name is looked up in the user data base to locate the user name's home directory). Where it gets funky is if the user data base does not contain absolute paths (don't do that) or $HOME does not contain an absolute path (don't do that either). Other forms of tilde expansion may also exist; for example, Bash expands ~- to the previous working directory, again all at the application level (and the shell is an application).

  • 3
    Neat, I didn't know about that last part. ~- is an alias for $OLDPWD and ~+N and ~-N can be used to get to the Nth positions from the top or bottom of the directory stack (as controlled by pushd and popd). Search for ~- in man bash or man zshexpn to learn more. – Adam Katz Oct 12 '17 at 21:59
  • "Practically, it is an absolute path as it is not relative to the working directory". However, it is relative to the current user home directory. ~/Mary references a different absolute path for users bob and alice, so yes, it is a relative path (?). – anneb Oct 13 '17 at 12:16
  • It's an absolute path, even if it's a different one for different users. I could also write /home/$SOMETHING/more/path, and the expansion depends on my environment but it expands to an absolute path. – alexis Oct 13 '17 at 21:20
  • @anneb: "relative" in this context has a specific technical meaning, which is "relative to the CWD of the process". Using other meanings of the English word "relative" is confusing. (See my answer on the linked duplicate) – Peter Cordes Oct 16 '17 at 5:14
  • @Peter Cordes. I would agree if there would be a clear and single technical definition of 'relative path'. One such definition is the Posix specification. That definition does not mention relativity to the cwd specifically. Therefore we should prefer Engilish to the specs? – anneb Oct 16 '17 at 12:12
4

The two most highly voted answers (EightBitTony and Stéphane) are correct: ~ is a shell alias that expands to the current user’s home directory.

On every Unix-like system, the users’ home directories are specified as absolute paths in the user database (e.g., /etc/passwd is traditionally used for local user accounts).

However, some of the answers and comments seem confused as to the definition of the terms absolute and relative – with some bordering on a post-modern interpretation that all paths are relative (to their parent directory or to /).


Definitions from the POSIX specifications

To provide some clarity, I figured it would be useful to add an answer that quotes the definitions as specified by The Open Group in POSIX.1-2008 (the definitions are linked to in Stéphane’s answer but not everybody follows the links):

A pathname is specified as

A string that is used to identify a file.

An absolute pathname is specified as:

A pathname beginning with a single or more than two <slash> characters

A relative pathname is specified as

A pathname not beginning with a <slash> character.

Also, how a POSIX shell expands the ~ is specified in Tilde Expansion.

2

Yes, ~/Mary is a relative path.

This question seems to be a question of definition. I am not sure if there exists an official systems wide definition for absolute path and relative path

There are two types of 'path': relative and absolute. An absolute path always points to the same resource. Relative paths point to a resource relative to something else.

When ~ is used, it is normally used to be expanded to the current user home directory. The home directory depends on the current user, so ~/Mary is relative to the current user home directory.

For example ~/Mary may expand to /home/bob/Mary for user bob and it may expand to /home/alice/Mary for user alice.

Some more examples
./Mary is relative to the current directory
../Mary is relative to the parent directory
~/Mary is relative to the current user home directory
Mary is relative to the current directory
/Mary is relative to the root directory. The root directory is fixed, so this is an absolute path

However, people might claim that even a root directory is relative to the current host. If you add a host to a path, it would become hostname:/Mary. But this is still not really an absolute path as 'hostname' is relative to the system that defines hostnames.

  • 1
    "The root directory is fixed" it isn't actually, but we mostly assume that it is. – plugwash Oct 13 '17 at 13:35
  • Personally, I think relative is assumed to mean, relative to your current path when someone says 'a relative path'. That of course is open to interpretation, but that's the beauty of language. How about, ~/Mary is an absolute path, the value of which can vary :) – EightBitTony Oct 13 '17 at 14:00
  • And $VAR/Mary is relative to the content of the $VAR variable and $(dirname -- "$0")/Mary is relative to the output of tha dirname command. – Stéphane Chazelas Oct 13 '17 at 14:36
  • 2
    You really think something as basic as relative and absolute path would have have "no official definition" after all these years of POSIX? That's wildly implausible (and wrong). – alexis Oct 13 '17 at 21:25
1

Let me offer a simple experiment:

[vttoth@host ~]$ cd /tmp
[vttoth@host tmp]$ mkdir "~"
[vttoth@host tmp]$ mkdir "~/Mary"
[vttoth@host tmp]$ ls -al "~"
total 12
drwxrwxr-x.  3 vttoth vttoth   17 Oct 12 20:24 .
drwxrwxrwt. 14 root   root   8192 Oct 12 20:24 ..
drwxrwxr-x.  2 vttoth vttoth    6 Oct 12 20:24 Mary
[vttoth@host tmp]$ cd "~/Mary"
[vttoth@host Mary]$ pwd
/tmp/~/Mary

Sure as heck looks relative to me.

However, if in the bash shell (same applies to many other shells) I do

[vttoth@host Mary]$ echo ~
/home/vttoth

it becomes evident that ~ is expanded by the shell into an absolute path.

In short, the question is ambiguous: the literal answer is that "~/anything" is a relative path, but one can guess that the question really is about how the shell expands the ~ symbol unless it is protected from expansion by the use of quotes.

I recommend reading the section titled tilde expansion in the bash man page, or the corresponding section(s) in the man pages of the preferred shell.

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