For example, I have a file myold_file
. Then I use ln
to create a hard link as mylink
:
ln myold_file mylink
Then, even by using ls -a
, I cannot tell which is the old one.
Is there anyway to tell?
You can't, because they are literally the same file, only reached by different paths. The first one has no special status.
.bashrc
is a file containing..." when we mean, "the relative path .bashrc
refers to a file containing...", this is a common conflation of categories and we should understand that whenever one refers to a path or a directory entry "being" a file, we mean the file to which it refers. With that understanding, two hard links can "be" the same file. Rejecting that convention in favour of formal language, they can't. Both stances have their place :-)
Commented
Apr 1, 2014 at 9:14
There is no direct, clean (reliable) way to do that. But under appropriate circumstances this can be possible (or at least probable). The problem is that there are two hard links but just one file. Change, modification and (maybe) creation time are stored for files (inodes) only but not for directory entries (the hard links). Thus the information you want can be taken from secondary effects only which can be easily destroyed by operations which are not related to the file. And you cannot even see whether it has been destroyed. You can only know that from the operational circumstances if you are precisely aware of them.
The creation of a hard link is a write operation to the directory which contains the link. Thus it updates the directory's mtime
. So if
the links are in different directories
and you know that none of these directories has been changed (file added, deleted, renamed or file metadata change) after the second hard link has been created then you can simply compare the mtime
s of the directories.
Special case: If one of the directories has an mtime
before the file's (inode's) mtime
and you can be reasonably sure that the file has not been written later than a short moment after its creation then this directory's link is the older one.
If the links are in the same directory (which seems to be the case in your question) then it gets worse. Then you can use
ls -lU
in order to get an impression of the order in which the entries have been created. That need not be the correct order as entries may be deleted so that new entries are made in the middle of the directory list. And as Gilles pointed out it doesn't work at all with newer filesystems.
ls -lU
trick won't work on modern filesystems (ext4, btrfs, zfs), there entries don't show up in creation order at all.
Commented
Mar 31, 2014 at 12:42
rm myold_file
then mylink
would still exist and work perfectly, as it is an equally good entry referring to the same underlying inode. Only when both have been deleted can the system discard the inode. Once hard linking has been used to create two file system entries referring to the same file, they are equivalent. (Note that "file" here means "an inode that holds the data for a file, as opposed to a directory). See: en.wikipedia.org/wiki/Inode
Commented
Mar 31, 2014 at 12:47
If you rely on the last modification time of the directories and you don't have knowledge of how and when those directories are changed, relying on mtime is going to lead you to be wrong some percentage of the time. The issue here is that the file is represented in the filesystem by an inode, not by a directory entry. The directory entry (filename) points to the inode, not the file.
I think I'd be doing some navel gazing about why I need to know which directory entry is older and how to avoid needing to know that.
I think this question is (quite reasonably) misguided as to what a hard link really is. I think however the most correct direct answer is 'They both are'.
Unix file systems normally store actual file contents and data in i-nodes, these do not have a path whatsoever, paths then have a many to one relationship to these i-nodes. Take as an analogy a person who goes by two names, Bob and Joe. One could not say that Bob is older than Joe or vice versa, they are just names for the same person.
If you want to retain the concept of an 'original' file and a new one you are likely looking for a symbolic link instead, these are more of an alias, just an instruction to the OS that it should operations to one path as if they were to another without changing the file structure underneath. (you can make these with "ln -s file link".
The crux of the answer given by several others above is that the every file name is a hard link to a file. There is no real original, just possibly a first one.
Think of a directory as a table that lists file names and inode-numbers.
Every hard link, including the first one, is an entry in a directory which assigns a "file name" to the inode number, so that you can access the file by that name.
The file is a collection of blocks on disk, managed and tracked by meta data stored in an inode. A file have one inode number.
Accessing a file's data via the file name is a three step process: The file name is looked up in the directory to obtain the inode number. The inode is then referred to to find the relevant disk block (or blocks) containing the data. Then finally those blocks are read/written.
So the take-home from all that is basically this: There is absolutely no difference between accessing file contents using the first ("original") or any subsequently created hard links.
If you foresee that you will need to differentiate between the earlier created (original) file and the one created by ln - you may do that when you create the link... by prefixing the name with an indicator, such as "myln".
ls > a; ln a b; rm a; ln b c
, which one is "more original" than the other?a
is gone, you are left withb
andc
...