Reputation: 543
I'm trying to findout if a folder is actually a hard link to another, and in that case, findout its real path.
I did a simple example in python in the following way(symLink.py):
#python 3.4
import os
dirList = [x[0] for x in os.walk('.')]
print (dirList)
for d in dirList:
print (os.path.realpath(d), os.path.islink(d))
"""
Given this directories structure:
<dir_path>\Example\
<dir_path>\Example\symLinks.py
<dir_path>\Example\hardLinkToF2 #hard link pointing to <dir_path>\Example\FOLDER1\FOLDER2
<dir_path>\Example\softLinkToF2 #soft link pointing to <dir_path>\Example\FOLDER1\FOLDER2
<dir_path>\Example\FOLDER1
<dir_path>\Example\FOLDER1\FOLDER2
The output from executing: C:\Python34\python <dir_path>\Example\symLinks.py is:
['.', '.\\FOLDER1', '.\\FOLDER1\\FOLDER2', '.\\hardLinkToF2']
<dir_path>\Example False
<dir_path>\Example\FOLDER1 False
<dir_path>\Example\FOLDER1\FOLDER2 False
<dir_path>\Example\hardLinkToF2 False
"""
In this example os.path.islink always returns False both for a hard or a soft link. In the other hand, os.path.realpath returns the actual path for soft links, not for the hard links.
I've made this example using python 3.4 in Windows 8. I have no clue if I am doing something wrong or if there is another way to achieve it.
Upvotes: 1
Views: 6353
Reputation: 171
Links to directories on Windows are implemented using reparse points. They can take the form of either "directory junctions" or "symbolic links". Hard links to directories are not possible on Windows NTFS.
At least as of Python 3.8 os.path.samefile(dir1, dir2)
supports both symbolic links and directory junctions and will return True
if both resolve to the same destination.
os.path.realpath(dirpath)
will also work to give you the real (completely resolved) path for both symbolic links and directory junctions.
If you need to determine which of the two directories is a reparse point, you can leverage os.lstat()
as os.path.islink()
only supports symbolic links.
import os
import stat
def is_reparse_point(dirpath):
return os.lstat(dirpath).st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT
Insofar as it may be valuable for testing, here are some useful utilities available in the Windows CMD shell.
Interrogate reparse point data:
>fsutil reparsepoint query <path to directory>
Create reparse points of both the "symbolic link" and "directory junction" variety *:
>mklink /d <symbolic link name> <path to target directory>
>mklink /j <junction name> <path to target directory>
You can read more about the difference between hard links and junctions, symbolic links, and reparse points in Microsoft's docs.
*Note that creating symbolic links typically requires Administrator privileges.
Upvotes: 3
Reputation: 1929
Not to bee too harsh, but I spent 1 minute googling and got all the answers. Hint hint.
To tell if they are hardlinks, you have to scan all the files then compare their os.stat
results to see if they point to the same inode. Example:
https://gist.github.com/simonw/229186
For symbolic links in python on Windows, it can be trickier... but luckily this has already been answered:
Having trouble implementing a readlink() function
(per @ShadowRanger in comments), make sure you are not using junctions instead of symbolic links since they may not report correctly. – ShadowRanger
https://bugs.python.org/issue29250
Upvotes: 1