How to copy a directory with symbolic links in Linux Bash?

BASH copy useful options. Dealing with symbolic links, preserve as it was or give them a new life.

There are two base methods of copying linux directories containing symbolic links. Symbolic links can be preserved or become regular files and directories which are independent of their source.

Copy files and preserve symbolic links

cp -rp source destination

In this method, we will get the exact copy of the source directory. Files and directories that have been symbolic links will also be symbolic links.

If the symbolic link was pointing to the file in the copied directory it will also point to the corresponding file in the destination directory.

If the symbolic link was pointing to the file outside copied directory it will point to the same file as in the source directory.

Symbolic links are poreserved as symbolic links.

Example

Let's make test file home.txt in home directory and test directory test1 with a test file file1.txt. We will also create two symbolic links (one to this file in the same folder and another to the file in home directory - one level UP)"

cd ~
echo "test in home 999" > home.txt
mkdir test1 
cd test1
echo "123" > file.txt
# create symbolic links
ln -s ./file.txt ./symlink.txt 
ln -s ../home.txt ./symlinkhome.txt
cd ~

After above operations

  • symlink.txt in test1 is linked to file.txt in test1
  • symlinkhome.txt in test1 is linked to home.txt in home directory

Now we can copy entire folder test1 preserving symbolic links.

cp -rp test1 test2

After the above operation

  • directory test2 is the exact copy of test1
  • symlink.txt in test2 is linked to file.txt in test2
  • symlinkhome.txt in test2 is linked to home.txt in home directory (the same file as above)

Now let's add something to symlink1.txt and symlinkhome.txt in folder test2.

echo "new line 1" >> ./test2/symlink.txt
echo "new line 2" >> ./test2/symlinkhome.txt

Let's check what happened to files

cat ./test1/file.txt  # (file unchanged)
cat ./test2/file.txt # (new line "new line 1" was added)

All below have the same content

cat ./test1/symlinkhome.txt
cat ./test2/symlinkhome.txt
cat ~/home.txt

Time to clean test area

rm -rf test1; rm -rf test2; rm ~/home.txt

Copy symbolic link as regular files and directories

Symbolic links may not work in a target directory, thus sometimes it is better to copy the file instead of a symbolic link.

When we use this method we will also get a copy of the source directory. We will copy symbolic links and they will start to exist as new, independent files, in the target directory.

The difference is that files and directories that have been symbolic links in the source directory will become regular files and directories. They will be the same as source objects at the time of making the copy.

After copying they will start to exist as independent objects not linked in any way to their sources. If we make any change of a file or a directory in the destination directory it WONT'T take effect on source objects. Objects in the new directory are independent, regular files and directories.

# copy symbolic links as regular files
cp -Lrp source destination

Example

As in the first example, we make a test file in home directory and make directory with a test file and two symbolic links (one to this file in the same folder and another to the file in home directory - one level UP).

cd ~
echo "test in home 999" > home.txt
mkdir test1 
cd test1
echo "123" > file.txt
ln -s ./file.txt ./symlink.txt 
ln -s ../home.txt ./symlinkhome.txt
cd ~

And the effect is the same

  • symlink.txt in test1 is linked to file.txt in test1
  • symlinkhome.txt in test1 is linked to home.txt in home directoryy

Now let's copy the entire folder test1 preserving symbolic links.

cp -Lrp test1 test2

After this operation directory, test2 is a copy of test1 but

  • symlink.txt in test2 is an independent file
  • symlinkhome.txt is an independent file

For the test let's add something to symlink1.txt and symlinkhome.txt in folder test2.

echo "new line 1" >> ./test2/symlink.txt
echo "new line 2" >> ./test2/symlinkhome.txt

And time to check what happened to the files:

cat ./test1/file.txt  # (file unchanged)
cat ./test2/file.txt # (file unchanged we only modified symlink.txt which is regular file not a symlink to file2.txt)
cat ./test1/symlinkhome.txt # is still linked to ~/home.txt
cat ./test2/symlinkhome.txt # is independent file
cat ~/home.txt # is linked to ./test1/symlinkhome.txt and wasn't modified

Don't forget to clean test area

rm -rf test1; rm -rf test2; rm ~/home.txt

Useful options of BASH cp

--help
-L, --dereference            always follow symbolic links in SOURCE
-R, -r, --recursive          copy directories recursively
-p                           same as --preserve=mode,ownership,timestamps

Copying files by scp or rsync

Symbolic links can be copied with rsync and scp commands.

All Right Reserved ©2005-2021

wiecko.com