2

How can I list all files with hardlinks and the associated paths?

It should be a sorted list, by the inode ID.

EDIT: sure, I mean all files with a hardlink number >=2

I thought about a list like

INODE_ID   FILEPATH

1234 /tmp/test1
1234 /tmp/test2
3245 /tmp/test4
3245 /tmp/test3
Zanna
  • 69,223
  • 56
  • 216
  • 327
2IRN
  • 695
  • 1
  • 7
  • 14

2 Answers2

5

Here is my solution with find:

find . -links +1 -type f -name '*' -printf '%i %p\n' | sort
  • . : search in current directory, you can change it to anything else, e.g: /, ~/ravexina, etc.
  • -links +1 : only files with more than of 1 link ( >= 2 ).
  • -type f : only files (not directories, sym links, pipe files, etc).
  • -name '*': all files with anything in their names no matter what.
  • -printf '%i %p\n': only print inode, file path and a new line\n.
  • sort : sort lines based on inodes.
Ravexina
  • 54,268
  • 25
  • 157
  • 179
  • oh nice, I couldn't figure out how to get the `-links` test to take "more than 1" (obviously I did not try hard enough). I don't think you need to specify `-k1` to `sort` since it will sort on the first column anyway – Zanna May 01 '17 at 10:03
  • Yeah, I figure it out from `-size` usage ;) – Ravexina May 01 '17 at 10:06
1

OK, in that case maybe

for i in /tmp/**; do 
  [[ -f "$i" ]] && 
  (( $(stat -c %h "$i") > 1 )) && 
  stat -c '%i %n' "$i"
done | sort -V

Notes

  • for i in * for each file in the current directory
  • [[ -f "$i" ]] && if it is a regular file and
  • (( $(stat -c %h "$i") > 1 )) if it has more than one hard link
  • stat -c '%i %n' print its inode number and name
  • | sort -V and sort that output "naturally"

You can replace * with the path to the files, for example /tmp/* which will cause the full path to be printed. If you want to search recursively, you can use shopt -s globstar and then ** in the path, for example /tmp/**

find has a -links test but it seems to only take an integer you'll have to read Ravexina's answer for a solution that uses it.

Zanna
  • 69,223
  • 56
  • 216
  • 327
  • Thanks, I didn't know shopt, but your version also list folders. I made a small modification: ```shopt -s globstar;for i in /tmp/**; do [[ -f "$i" ]] && (( $(stat -c %h "$i") > 1 )) && stat -c '%i %n' "$i"; done | sort -V``` – 2IRN May 01 '17 at 08:58
  • ah ok - edited it :) for `shopt` see [this page of the manual](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html) – Zanna May 01 '17 at 09:09