cp into destination hierarchy with symbolic link?

7,210

Solution 1

for any file copying I would suggest rsync over cp because it has a much finer control what should be copied and how. In your case just give the commands:

cd SOURCE
rsync -K -a . DEST

The -K option does exactly what you want: -K, --keep-dirlinks treat symlinked dir on receiver as dir

Solution 2

Since cp won't copy any directory in SOURCE over any symlink in DEST, one option is to copy those directories separately for each symlink.

Approach using find

cd DEST
cp -Rf SOURCE/* .
find -type l -exec bash -c 'cp -Rf "SOURCE/$0"/* "$0"' {} \;

Details

  • -type l restricts find to symlinks.
  • -exec bash -c '...' {} \; executes ... in a bash subshell for every found symlink, passing {} (the relative path to the symlink) as fitst argument ($0).
  • cp -Rf "SOURCE/$0"/* "$0" copies the contents of the corresponding source directory into the directory the symlink points to.
  • The cp command has to be invoked using bash, so the glob (asterisk) will get expanded.

Cautions

  • I suggest substituting cp with echo (or -Rf with -Ri) to make sure find does what you're expecting.
  • Without knowing the exact directory structure and the symlinks present in DEST, I can't guarantee that I anticipated all possible oddities.
Share:
7,210

Related videos on Youtube

est
Author by

est

Updated on September 18, 2022

Comments

  • est
    est almost 2 years

    I am trying to write a site deploy script that will copy files like so:

    SOURCE

    .
    ..
    src/
    html/
    

    DEST

    .
    ..
    src/
    html/ -> /var/www/ftproot/mysite
    

    I want the files in SOURCE html to go to DEST /var/www/ftproot/mysite.

    The script was:

    cd SOURCE
    cp -Rf * DEST
    

    Every time I run the script, I get this error:

    cp: cannot overwrite non-directory 'html' with directory `html'
    

    From this, I deduce that cp cannot automatically copy files into DEST when DEST has symbolic links.

    Notes:

    1. Following the cp manual, I set POSIXLY_CORRECT to 1. This doesn't work.

    2. I had to link site html to ftproot/mysite and not vice versa because the ftp users have weird access modes.

    3. This guy modified cp source code and recompiled it. I don't want to do that to a production server.

    Any ideas on how to solve this?

    • est
      est over 11 years
      @Dennis Thank you, answers are: 1. yes (start with l when ls -l) 2. Ubuntu 10.04 server 3. Not safe to assume that
    • est
      est over 11 years
      @Dennis yes you are correct. I edited my post.
  • Dr. Thomas C. King
    Dr. Thomas C. King over 6 years
    Thank you for this. Exactly what I was looking for after cp -aPv --remove-destination started failing when we changed a directory to a symlink in the destination.