40

Recently I created a link with the following:

sudo ln -n originalFileLocation

How do I delete a hard link?

hawkeye
  • 3,877
  • 7
    FYI: ln -n /path/to/file creates a file named file in the current directory and is shorthand for ln --no-dereference /path/to/file. This means that if /path/to/file is a symbolic link, the newly created hardlink will point to that symlink instead of the target of the symlink. – Lekensteyn Nov 05 '11 at 10:28
  • 3
    Clarification required. If is not a symbolic link, then rm <resulting hardlink> will delete the inode referenced by , which also results in delisting all the directory entries referencing that inode, including . Use unlink to only remove the directory entry . – Craig Hicks May 09 '20 at 18:29

4 Answers4

56

You can delete it with rm as usual: rm NameOfFile. Note that with hard links there is no distinction between "the original file" and "the link to the file": you just have two names for the same file, and deleting just one of the names will not delete the other.

Prateek
  • 2,561
  • 2
    Also ote you will need to rm it as root (use sudo), if you created it with the command you provided (as super-user). – Rafał Cieślak Nov 05 '11 at 11:38
  • 4
    @RafałCieślak: Wrong. All hard-links to an inode share the same access permissions, that of the inode. To delete, i. e. “unlink”, a directory entry of a file you need write permissions on the inode of that file and on the directory that contains the entry that you want to delete. Therefore it's irrelevant which privileges were used to create the hard-link. They may just happen to (still) be the same as at the time of creation. – David Foerster Nov 29 '16 at 11:45
  • Yes, misleading. I see that the idea is that rm removes the name only and the file is only removed once there is no name pointing to it, but still it is misleading. At first, it suggests that there is no way to unlink without deleting the file as well, but I just did it with "unlink ". Simpler conceptually to do unlink. – Dominic108 Oct 23 '21 at 21:37
  • @CraigHicks What do you mean by "The answer is only correct if..."? What will rming a hard link do that's incorrect? – Daniel Kaplan Feb 05 '22 at 09:12
  • 1
    @DanielKaplan - My comment was wrong and I have deleted it. Thanks. – Craig Hicks Feb 05 '22 at 19:34
8

Actually rm doesn't work:

[user@localhost Products]$ rm AZP/
rm: cannot remove `AZP/': Is a directory
[user@localhost Products]$ rm -r AZP/
rm: cannot remove `AZP': Not a directory

What works is unlink AZP.

Bunyk
  • 207
  • 3
    Are you sure yours was a hard link? Hard links are just like files iirc. – Seth Mar 12 '14 at 16:59
  • @Seth, actually I don't remember what was that, but it doesn't want to remove as you could see. Somebody told me to use unlink and it worked. :) – Bunyk Mar 26 '14 at 21:21
  • That's probably because AZP was a file, not a directory, but I couldn't be sure without more information. Unlink should always work though, so no problems there. – Seth Mar 26 '14 at 22:19
  • 2
    AZP/ looks like a directory, rm doesn't operate on directories without the recursive flag. Also according to the coreutills docs. >>> Most systems prohibit making a hard link to a directory; on those where it is allowed, only the super-user can do so (and with caution, since creating a cycle will cause problems to many other utilities). – ThorSummoner Mar 24 '16 at 17:04
  • 5
    Hard-links to directories are prohibited. If AZP is a symbolic link to a directory (or anything else) rm AZP/ will not work because rm thinks its a directory (because of the / at the end). However rm AZP will work just fine. -1 – David Foerster Nov 29 '16 at 11:40
2

I have this script to remove redundant hard links. But take care - it is quite dangerous.

#!/bin/bash
clear
echo Reduce redundant hardlinks in the current folder
echo ------------------------------------------------
echo 
echo "  $(basename $0) [-R]"
echo "      -R means recursive"
echo 
read -p "You can break by pressing Ctrl+C"
echo
ask=1
if [ a$1 == "a-R" ]; then  recursive=" -R "; fi

for i in $(ls -i $recursive | awk '{print $1}' | uniq --repeated | sort); 
do 
    echo "Inode with multiple hardlinked files: $i"
    first=1
    for foundfile in $(find . -xdev -inum $i);
    do 
        if [ $first == 1 ]; then
            echo "  preserving the first file:  $foundfile"
            first=0
        else
            echo "  deleting the redundant file:    $foundfile"  
            #rm $foundfile  
        fi
    done 
    if [ $ask == 1 ]; then 
        read -p "Delete all the rest of redundant hardlinks without asking? y/N "
        if [ a${REPLY,,} == "ay" ]; then  ask=0; fi
    fi  
#   read -p "pause for sure"
    echo
done
echo "All redundant hardlins are removed."
echo
muru
  • 197,895
  • 55
  • 485
  • 740
xerostomus
  • 990
  • 9
  • 20
1

If you want to remove only the link and thus keep the original file, you have to use unlink.

fbo72
  • 29
  • Have you read what unlink(1) does? It's a shallow wrapper around the unlink(2) system call, the same system call that rm(1) uses for all files that aren't directories. – David Foerster Nov 29 '16 at 11:42
  • 3
    This answer is misleading. With hardlinked files there's no distinction between "link" and "original file"; all hardlinks refer to the same file/content/inode, represented by different directory entries. unlink, despite it's name, will not separate a hardlinked into two separate files, but remove the "unlinked" directory entry (but not the file/content/inode, as long as the link count is > 1). – Murphy May 04 '17 at 22:29