I'd like to recursively convert soft links to hard links in a directory. I've tried something like this:
for f in *; do (mv $f{,~} && ln $(readlink $f~) && rm $f~) done
…but it has two major problems:
- not recursive
- picks up files that are not symbolic links
It would be nice to somehow feed the above line to find -type l
, but i'm not sure how to do that.
Best Answer
This command should work:
How it works:
find -type l
finds all links in the current directory.-exec bash -c '...' {} \;
invokes bash to execute...
.It passes
{}
– the name of the link that's currently being processed ‐ as an argument, which bash can access as$0
.readlink -m "$0"
returns the absolute path of the symbolic link's destination.ln -f "$(readlink -m "$0")" "$0"
overwrites (-f
) the symbolic link$0
with a hard link to its target.If the link cannot be converted for some reason, it will remain untouched and ln will print an error message.