I have the following directory structure
/symdir sym1 -> ../dir1 sym2 -> ../dir2 hello.txt
And then
/dir1 some files here /dir2 more files
I would like to replace the symlinks in symdir (sym1, sym2) with the originals. I.e.
some_awesome_bash_func symdir symdir_output
Would create
/symdir_output /dir1 some files here /dir2 more files hello.txt
How would I accomplish this?
Conclusion. To remove a symbolic link, use either the rm or unlink command followed by the name of the symlink as an argument. When removing a symbolic link that points to a directory do not append a trailing slash to the symlink name.
The rm command is the dedicated tool for deleting files and directories from the system. Because the symlink itself is a file, we can use the rm command to remove it. The following rm command will remove the symlink. To remove multiple symlinks, use rm as you would to remove multiple files.
We can use the -l option of rsync for copying symlinks. rsync copies the symlinks in the source directory as symlinks to the destination directory using this option. Copying the symlinks is successful in this case.
The only way to fix these broken symlinks is by deleting them. Your system contains hundreds of dangling links and no one has the time to check for these links manually. In such cases, Linux tools and commands prove to be really helpful.
My very personal trick for files (not directories):
sed -i '' **/*
Note that I'm using **
which uses the bash globstar option, you may have to enable it beforehand:
shopt -s globstar
I trick sed
to do the job, by using an implementation detail of the sed
inplace mode.
sed
is a tool to edit streams of text. The -i
option of sed
means inplace
, the empty string ''
is the instruction set: so there's no instruction, sed
will do nothing. **/*
is a bash globstar
pattern meaning "all files and all folders, at all depth, from here".
The algorithm sed
uses to edit a file inplace is:
As I'm asking no transformations (the empty string), the algorithm can be simplified as:
The temporary file is a real file, sed
completly ignores that the input file was a symlink, it just reads it. So at the last step, when sed
moves the temporary file over the real file, it "overwrite" the symlink with a real file, that's what we wanted.
This also explains why it won't work to transform a "symlink to a directory" to a real directory: sed
works on file contents.
You can do this easily with rsync:
rsync symdir/ symdir_output/ -a --copy-links -v
(-a means preserve basically every detail about the files, --copy-links overrides -a to turn symlinks into the real files/directories, and -v is for verbose)
Edit:
Sorry, my solution doesn't do exactly what you asked for. It will preserve the symlink's names instead of using the destination names. symdir_output would have sym1 and sym2 instead of dir1 and dir2 (though sym1 and sym2 would be a real copy of dir1 and dir2). Hope it still works for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With