Results 1 to 6 of 6

Thread: Symbolic Links To Hard Links

  1. #1
    Join Date
    Oct 2008
    Beans
    208
    Distro
    Ubuntu 10.04 Lucid Lynx

    Symbolic Links To Hard Links

    Hey all,
    I have a directory containing symbolic links to files on the same filesystem (specifically /dev/sda5, ext3), which I would like to change to hardlinks. I wanted to know if there is a quick way to convert symlinks to hardlinks, without manually recreating each using the command line. Does anybody know of a script that can do this?

    Thanks in advance.

  2. #2
    Join Date
    Oct 2008
    Beans
    208
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: Symbolic Links To Hard Links

    UPDATED: This should now be usable, but feel free to improve upon what I've got so far. This bash script will convert all symlinks found in a given directory to hardlinks. Not heard of many people with this problem, but I needed it once, and it was a good learning experience.

    Code:
    #!/bin/bash
    #Converts all symbolic links in a directory to hard links. See http://ubuntuforums.org/showthread.php?t=1508728 for any updates/problems.
    if [ -d $1 ] ; then
        echo "About to convert all symlinks in '$1' . Continue? [y/N]"
        read confirm
        if [ $confirm == y ]; then
            cd "$1" &&
            FOLDER="*"
            for file in $FOLDER
            do
                if [ -L "$file" ]; then
                    target=$(readlink "$file")
                    echo "Converting link to $file"
                    mv "$file" "$file.old" &&
                    ln "$target" "$file" &&
                    rm "$file.old"
                else
                    echo "$file not a symlink, skipping"
                fi
            done
        else
            echo "Exiting. No changes made."
        fi
    
    else
        echo "$1 is not a directory, exiting."
    fi
    exit
    I've used this as an excuse to try out some slightly more complicated bash scripting. If you have a similar problem to me, copy and paste the following into a blank text file.
    Save it as something sensible somewhere sensible, making it executable. Then run the script by changing directory to where you saved it, and run it with the directory of symbolic links you want to convert as an argument.
    Last edited by ks07; July 5th, 2010 at 12:46 AM. Reason: Updated Script

  3. #3
    Join Date
    Nov 2010
    Beans
    1

    Re: Symbolic Links To Hard Links

    Great script, it helped me. I needed it to make a directory containing links movable to another hard disk, because moving symlinks doesn't change the target files' location.
    The only thing I miss from it is recursivity, because I have many subdirectories to convert symlinks to hardlinks in. Unfortunately, I can't add this feature to the script.
    But you can find any symbolic link recursively in a directory if you type this command:
    Code:
     find the_directory_to_search_in -type l
    Note that hard links can't point to directories - you have to make individual hard links pointing to the contents of the directory.
    Last edited by fattila2; November 11th, 2010 at 05:23 PM.

  4. #4
    Join Date
    Apr 2011
    Beans
    2

    Re: Symbolic Links To Hard Links

    This program does not work if there is a space in the directory.

    Here is the fix:

    Code:
    #!/bin/bash
    #Converts all symbolic links in a directory to hard links. See http://ubuntuforums.org/showthread.php?t=1508728 for any updates/problems.
    if [ -d "$1" ] ; then
        echo "About to convert all symlinks in '$1' . Continue? [y/N]"
        read confirm
        if [ "$confirm" == "y" ]; then
            cd "$1" &&
            FOLDER="*"
            for file in $FOLDER
            do
                if [ -L "$file" ]; then
                    target=$(readlink "$file")
                    echo "Converting link to $file"
                    mv "$file" "$file.old" &&
                    ln "$target" "$file" &&
                    rm "$file.old"
                else
                    echo "$file not a symlink, skipping"
                fi
            done
        else
            echo "Exiting. No changes made."
        fi
    
    else
        echo "$1 is not a directory, exiting."
    fi
    exit

  5. #5
    Join Date
    Apr 2011
    Beans
    2

    Re: Symbolic Links To Hard Links

    For recursive operation, I saved the script below to this location: "/usr/local/bin/symtohard". Any directory in your $PATH will work just fine. After putting it there, make sure to run:
    Code:
    chmod +x /usr/local/bin/symtohard

    Code:
    #!/bin/bash
    #Converts all symbolic links in a directory to hard links. See http://ubuntuforums.org/showthread.php?t=1508728 for any updates/problems.
    if [ -d "$1" ] ; then
        echo "About to convert all symlinks in '$1' "
    #    if [ "$confirm" == "y" ]; then
            cd "$1" &&
            FOLDER="*"
            for file in $FOLDER
            do
                if [ -L "$file" ]; then
                    target=$(readlink "$file")
                    echo "Converting link to $file"
                    mv "$file" "$file.old" &&
                    ln "$target" "$file" &&
                    rm "$file.old"
                else
                    echo "$file not a symlink, skipping"
                fi
            done
    #    else
    #        echo "Exiting. No changes made."
    #    fi
    
    else
        echo "$1 is not a directory, exiting."
    fi
    exit
    The run this monster with the correct path to recursivly replace all symlinks. This DOES NOT ASK FOR CONFORMATION, it just runs through. Be careful!

    Code:
    find /directory_with_syms -type l -exec dirname '{}' \; | sort | uniq | xargs -L 1 -I {} symtohard "{}"
    If you would like to be prompted per directory (but not per file) add "-p" right after xargs.

    Happy hardlinks!
    Last edited by esromneb; April 20th, 2011 at 10:23 PM. Reason: notification

  6. #6
    Join Date
    Nov 2008
    Location
    Darmstadt, Germany
    Beans
    Hidden!
    Distro
    Ubuntu 18.04 Bionic Beaver

    Re: Symbolic Links To Hard Links

    Currently fails to detect cross-device links, so those links will be renamed <filename>.old.

    Here's how to revert:

    Code:
    for i in $(find . -iname '*.old' -print | rev | cut -f2- -d. | rev); do mv -vi $i.old $i; done

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •