Shell Script – Determine if a File is a Hard Link or Symbolic Link

fileshard linkshell-scriptsymlink

I'm creating a shell script that would take a filename/path to a file and determine if the file is a symbolic link or a hard link.

The only thing is, I don't know how to see if they are a hard link. I created 2 files, one a hard link and one a symbolic link, to use as a test file. But how would I determine if a file is a hard link or symbolic within a shell script?

Also, how would I find the destination partition of a symbolic link? So let's say I have a file that links to a different partition, how would I find the path to that original file?

Best Answer

Jim's answer explains how to test for a symlink: by using test's -L test.

But testing for a "hard link" is, well, strictly speaking not what you want. Hard links work because of how Unix handles files: each file is represented by a single inode. Then a single inode has zero or more names or directory entries or, technically, hard links (what you're calling a "file").

Thankfully, the stat command, where available, can tell you how many names an inode has.

So you're looking for something like this (here assuming the GNU or busybox implementation of stat):

if [ "$(stat -c %h -- "$file")" -gt 1 ]; then
    echo "File has more than one name."
fi

The -c '%h' bit tells stat to just output the number of hardlinks to the inode, i.e., the number of names the file has. -gt 1 then checks if that is more than 1.

Note that symlinks, just like any other files, can also be linked to several directories so you can have several hardlinks to one symlink.