Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
    
@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 Jan 14 '13 at 3:40
    
@Dennis yes you are correct. I edited my post. –  est Jan 14 '13 at 3:52
add comment

2 Answers 2

up vote 1 down vote accepted

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

share|improve this answer
add comment

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|improve this answer
    
Clever use of find. Thanks –  est Jan 14 '13 at 4:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.