I'm currently writing a script that searches through a directory and displays files with multiple hard links. The way I have it set up, is that it displays the i-node number and then each of the link names. In addition to this, I need to know if there are any hard links outside of the searched directory and if so, how many. Which I'm not completely sure how to do.
I understand the $4 is the number of hard links, however does that include any links that are found outside of the current directory? If not, then what exactly do I need to do to get a total number of hard links in and out of the current directory?
The second column is the number of disk blocks required to house the file. Generally the value is 512 byte blocks, though some versions of find might default to 1024 byte blocks.
The fourth column is the number of links, but only if the file is a regular file. If it is a directory it is the number of files contained/referenced in the directory.
Because links (old timers call them links as symbolic links were introduced later) cannot span filesystems, I'd approach the problem by executing a find on the whole file system and matching inodes for files that are listed within the target directory. The following is a way to do this and assumes that the target directory is the current working directory.
#!/usr/bin/env ksh
p=$(df -h . )
find ${p##* } -type file -ls 2>/dev/null | awk -v cwd="$(pwd)/" '
{
if( $4 > 1 ) # only care about files with multiple hardlinks
{
dir = $NF;
sub( "[^/]+$", "", dir ); # lop off the filename
if( dir == cwd ) # collect for printing only files in the target directory
listit[$1]++;
paths[$1] = paths[$1] $NF " "; # collect paths associated with the inode (regardless of directory)
}
}
END {
for( f in listit )
{
x = split( paths[f], a, " " ); # split paths for a "vertical" listing
printf( "%s\n", f ); # print the inode number
for( i = 1; i <= x; i++ ) # list each path
printf( "\t%s\n", a );
printf( "\n" );
}
}
'
Thanks for the replies. Just one last question though. In the fourth column above, is that the total number of hard links for that file or just the number of links in that directory?
After reading that put it to the test.
p=$(df -h .) # free hard disk space in the current directory in a human readable format
echo ${p##* } # there's a space after the *