4

I want to delete all hardlinks for a specific file.

The usage would be script somefile, this would count the hardlinks for the file somefile, then it's going to delete all hardlinks keeping this file only.

The command

find / -samefile file-name | xargs rm

will do the needed but this deletes the original file also.

Also you can use

find / -inum Inode-number | xargs rm

But this also would delete the original file.

My first script veriosn looks like

#!/bin/bash
file=$1
inode=`ls -li $file | cut -d" " -f1`

find / -inum $inode | xargs rm

But as I said above this would delete the original file also, so how to keep the first instance and remove others.

2 Answers 2

5

You can use ! with the path to the original file to exclude it:

$ find . -samefile bar                   
./baz
./bar
$ find . -samefile bar ! -path "./bar"   
./baz

The path must match what find outputs, so use absolute paths if you search from /.

Notes:

  • find has a -delete command
  • If combining with xargs, use -print0 and -0:

    find  . -samefile bar ! -path "./bar" -print0 | xargs -0 rm
    
  • Use stat to get the inode number directly:

    $ stat -c '%i' bar
    257643
    
0

This works for both absolute and relative filenames plus it doesn't print any "Permission denied" dialogs and prints Deletion failed: <filename> when deleting fails:

find / -samefile "$1" \! -path "${PWD}/$1" \! -delete -printf 'Deletion failed: %p\n' 2>/dev/null

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .