Let's suppose Mary is a directory. Is the following path ~/Mary relative?
6 Answers
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
- 3,723
- 21,373
-
9
../Maryin/home/Bobwould not refer to/home/Bob/Mary, it would refer to/home/Mary. Perhaps you meant to write/home/Bob/something? – elaforma Oct 12 '17 at 13:10 -
21I 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
2on the system. If yes, then~2wouldn'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
-
~was probably chosen because it was easy to type on a US keyboard. – Thorbjørn Ravn Andersen Oct 12 '17 at 20:00 -
@ThorbjørnRavnAndersen Which US keyboard? Aside from the alphanumeric keys, keyboard layouts in the 80s and earlier were not very standardized. – 8bittree Oct 12 '17 at 21:11
-
@chepner yes, I struggled to find a word other than alias that made for easy reading. – EightBitTony Oct 13 '17 at 07:02
-
-
@EightBitTony Your edit was correct, as Kroltan already commented. I reverted the last edit. – Dubu Oct 13 '17 at 10:03
-
If you're in
/home/Bobthen../Maryis/home/Mary, not/home/Bob/Mary. The relative path to/home/Bob/Maryfrom/home/Bobwould be./Mary, or justMary. – Bob Jarvis - Слава Україні Oct 13 '17 at 11:08 -
@BobJarvis Darn, yes. Thrown the baby out with the bath water. For user
Bobfrom/home/Bob, a../Marywould be/home/Mary, but a~/Marywould be/home/Bob/Mary. Hopefully fixed now. – Dubu Oct 13 '17 at 12:10 -
@8bittree I could not locate an image of a PDP-7 keyboard. – Thorbjørn Ravn Andersen Oct 13 '17 at 23:14
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
- 544,893
-
2
-
2@AdamKatz, what about a wildcard
$HOMElikeHOME='*'(see edit) ;-) – Stéphane Chazelas Oct 12 '17 at 18:21 -
1
-
3Looks like
HOME=.works too, and you can have a little fun withHOME='~'; cdgenerating an error likebash: cd: ~: No such file or directory. Wow, this rabbit hole is deep... – Adam Katz Oct 12 '17 at 21:48
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).
- 8,678
- 5,829
- 3
- 31
- 43
-
3Neat, I didn't know about that last part.
~-is an alias for$OLDPWDand~+Nand~-Ncan be used to get to the Nth positions from the top or bottom of the directory stack (as controlled bypushdandpopd). Search for~-inman bashorman zshexpnto 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 05: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
-
@anneb: interesting point. I guess I'd say that definition needs to be applied to the path proper, which is the result of tilde-expansion on
~/Mary. Unless you use it in a context which doesn't do tilde-expansion, or if$HOME=.. So POSIX doesn't mess around trying to describe~/Maryat all, and the most accurate (but less useful) thing to say is that what most people mean when they say~/Maryisn't actually a path yet. But yes if you did use it as a path (without expansion), it would be relative. – Peter Cordes Oct 16 '17 at 12:24
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.
- 12,950
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.
- 121
-
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,
~/Maryis an absolute path, the value of which can vary :) – EightBitTony Oct 13 '17 at 14:00 -
And
$VAR/Maryis relative to the content of the$VARvariable and$(dirname -- "$0")/Maryis relative to the output of thadirnamecommand. – Stéphane Chazelas Oct 13 '17 at 14:36 -
2You 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
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.
- 294
Maryto be a directory in not needed for your question. – hildred Oct 12 '17 at 19:58/. – Sparhawk Oct 13 '17 at 12:18