1

I would like to know if it is possible identify whether a file (or link) is a hardlink or not, on Linux. For instance, If I created:

dd if=/dev/urandom bs=1024 count=10000 of=file_10MB conv=notrunc
ln file_10MB file_10MB_link1

I would like to create a check function, that could be used like this:

if is_hardlink("file_10MB_link1"):
    pass

How can I use Python to check if a file is a hardlink?

not2qubit
  • 11,992
  • 7
  • 83
  • 112
uilianries
  • 2,854
  • 12
  • 25

3 Answers3

5

I believe you're looking for "files which have a link count greater than 1"

for that you can use:

def more_than_one_link(filename):
    os.stat(filename).st_nlink > 1
Anthony Sottile
  • 49,611
  • 12
  • 110
  • 158
  • I think he wants a function that will be true for `file_10MB_link1` but false for `file_10MB`. Checking the link count won't do that, since they'll both return `st_nlink == 2` – Barmar Apr 17 '20 at 21:34
  • @Barmar there's no such thing -- they are the same inode – Anthony Sottile Apr 17 '20 at 21:35
  • I know, that's what I said in my answer. – Barmar Apr 17 '20 at 21:36
  • I appreciate your answers, but like @Barmar said, I need to identify a hardlink, not counting the nodes, otherwise, I'll need to check each file for every folder. Seems like there is no good option for that case, so I'll accept the code. Thanks a lot! – uilianries Apr 18 '20 at 00:54
  • 1
    Are you trying to find out if it's a hard link to a specific file? You can check the device and inode numbers to see if they're the same. – Barmar Apr 18 '20 at 01:12
  • I see, that's I'm looking for! – uilianries Apr 19 '20 at 00:57
2

No, it's not possible. There's nothing that distinguishes the original file from the hard link. They're just two names that refer to the same inode number, which represents the file contents.

You can use the code in Anthony Sottile's answer to tell if the file has multiple links to it, but you can't tell which is the original.

Barmar
  • 669,327
  • 51
  • 454
  • 560
0

The answer is that that it depends on the filesystem and (exact) OS you are using. For example, if you are using NTFS (although unlikely in a native Linux context) it allows for a wide range of NTFS specific features including hardlinks and junctions. So while in Windows they use link numbers for hardlinks, Linux OS use inodes.

You would need specific kernel drivers or a forensic OS to be able to read all those, as normal Linux are using only inodes, and would need to be counted and time-stamp analyzed to decided what is the original file vs. a later created hardlink(s).

As python can create both hardlinks and softlinks via:

os.link()    # Create a hard link
os.symlink() # Create a symbolic link

(TL;DR the long docs above) there should be a way for you to check the link type, although it may require quite a bit of disc processing (searching and comparing).

For the exact detection check the built-in os functions, explained in this answer.
[islink(), parse_reparse_buffer(), readlink()]

not2qubit
  • 11,992
  • 7
  • 83
  • 112