35

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?

3
  • 2
    Counterquestion: If you do ls > a; ln a b; rm a; ln b c, which one is "more original" than the other? a is gone, you are left with b and c...
    – glglgl
    Commented Apr 2, 2014 at 5:38
  • 2
    What are you trying to achieve? What are you trying to achieve? There is no "original" as such. A file is an inode containing meta data and a collection of blocks containing data. A directory can contain a link to the file, and this link is the file name and the inode number. You can create any number of links to a file. Files may never have less than one link.
    – Johan
    Commented Apr 2, 2014 at 7:29
  • For a detailed explanation of the accepted answer of this question: See the accepted answer of that question.
    – Utku
    Commented Oct 5, 2015 at 14:51

6 Answers 6

101

You can't, because they are literally the same file, only reached by different paths. The first one has no special status.

9
  • 4
    This is clearly the right answer: the OP's question is based on a misunderstanding. Commented Mar 31, 2014 at 9:33
  • 9
    @Adnan Actually, no: the two hard links are the same file. They're different directory entries. Jenny D's terminology is correct. Commented Mar 31, 2014 at 12:43
  • 1
    @Gilles I don't see how it can be correct. Two hard links aren't two files; hard links aren't files. They point, hence link, to the same file (which is the physical location on the disk). Saying that "two hard links are literally the same file" is wrong.
    – Adi
    Commented Mar 31, 2014 at 12:56
  • 1
    @JennyD And that's pretty much the only way I heard "hard link" being used; a filesystem pointer to an inode. Well, I guess we're all wrong and right. I will cease arguing this as it's pointless. You're answer seems correct to me, you have a +1 from me, and I'll leave it at that.
    – Adi
    Commented Mar 31, 2014 at 12:58
  • 6
    Saying that a hard link "is" a file is comparing things of different categories, which is technically incorrect. But given that we generally say, ".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
16

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

  1. the links are in different directories

  2. 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 mtimes 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.

17
  • 2
    No mention of selinux, audit trails, or spying on the filesystem journal??? smirk Without an audit trail, there's no way to know -- anything else is a calculated guess
    – Ricky
    Commented Mar 31, 2014 at 5:57
  • 1
    @mikeserv If you want to teach others this way then you should at least learn to quote correctly. It does not say "which file" in the question. And even if it did then this would be just a wording problem and throwing some brain at understanding the question would easily reveal what it is really about. Commented Mar 31, 2014 at 9:48
  • 4
    The directory mtime trick will work if the circumstances are right (which is rare). However, the way you're presenting it, you'll sometimes come to the opposite conclusion. The directory mtime is only a worthwhile indication if it's equal to the file's ctime. But the 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
  • 2
    @mikeserv - the OP's question is based on a misunderstanding. If they did 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
  • 1
    -1 because, although the info about how the directory changes in some file systems when updating the tables, this answer fails to clear up the miss-understanding present in the question that "original file" is not a property in the case of multiple hardlinks to a single inode. In that sense while is in anecdotally interesting it is not what most people landing on this question should learn about the fundamental concept of hardlinks. This issue is not a lack of a "direct clean way to do it", the issue is that there is no "it" in the first place.
    – Caleb
    Commented Apr 2, 2014 at 10:34
10

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.

8

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".

1
  • You know, Bob/Joe can get really sensitive about his age... The hard/soft link comparison is a good one - especially when you consider that a hard-link will just get an entry added into a directory file - an already existing inode - but a soft-link is a file in its own right, and is thus assigned its very own inode. Still, in both cases, the modification time is only relevant for the linked file, as the only modifications that can be done to a link of any significance would just be creation/deletion.
    – mikeserv
    Commented Apr 2, 2014 at 15:59
2

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.

0

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".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .