How to copy directory structure without removing symlinks?

Clash Royale CLAN TAG#URR8PPP
up vote
25
down vote
favorite
I need to "install" a bunch of files to another directory keeping the directory structure of the source files intact. For example, if I have ./foo/bar/baz.txt going to /var/www/localhost/webroot/ I want the result to be /var/www/localhost/webroot/foo/bar/baz.txt. rsync has this capability in --relative, but when I did this I discovered it wasn't friendly to symlinks:
$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx 1 www-data www-data 15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx 1 root root 13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var
So you see the symlink is no longer a symlink – the files were copied to the wrong place!
rsync also has the --no-implied-dirs option, that superficially seems to do what I want, but it only works as I intend when not doing a recursive rsync, so I have to:
find . -type f -print0 | xargs -0I rsync -R --no-implied-dirs /var/www/localhost/webroot/
Is there any more direct way to accomplish this mirroring of files without wiping out intermediate symlink directories (with or without rsync)?
rsync symlink mirror
add a comment |
up vote
25
down vote
favorite
I need to "install" a bunch of files to another directory keeping the directory structure of the source files intact. For example, if I have ./foo/bar/baz.txt going to /var/www/localhost/webroot/ I want the result to be /var/www/localhost/webroot/foo/bar/baz.txt. rsync has this capability in --relative, but when I did this I discovered it wasn't friendly to symlinks:
$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx 1 www-data www-data 15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx 1 root root 13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var
So you see the symlink is no longer a symlink – the files were copied to the wrong place!
rsync also has the --no-implied-dirs option, that superficially seems to do what I want, but it only works as I intend when not doing a recursive rsync, so I have to:
find . -type f -print0 | xargs -0I rsync -R --no-implied-dirs /var/www/localhost/webroot/
Is there any more direct way to accomplish this mirroring of files without wiping out intermediate symlink directories (with or without rsync)?
rsync symlink mirror
add a comment |
up vote
25
down vote
favorite
up vote
25
down vote
favorite
I need to "install" a bunch of files to another directory keeping the directory structure of the source files intact. For example, if I have ./foo/bar/baz.txt going to /var/www/localhost/webroot/ I want the result to be /var/www/localhost/webroot/foo/bar/baz.txt. rsync has this capability in --relative, but when I did this I discovered it wasn't friendly to symlinks:
$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx 1 www-data www-data 15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx 1 root root 13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var
So you see the symlink is no longer a symlink – the files were copied to the wrong place!
rsync also has the --no-implied-dirs option, that superficially seems to do what I want, but it only works as I intend when not doing a recursive rsync, so I have to:
find . -type f -print0 | xargs -0I rsync -R --no-implied-dirs /var/www/localhost/webroot/
Is there any more direct way to accomplish this mirroring of files without wiping out intermediate symlink directories (with or without rsync)?
rsync symlink mirror
I need to "install" a bunch of files to another directory keeping the directory structure of the source files intact. For example, if I have ./foo/bar/baz.txt going to /var/www/localhost/webroot/ I want the result to be /var/www/localhost/webroot/foo/bar/baz.txt. rsync has this capability in --relative, but when I did this I discovered it wasn't friendly to symlinks:
$ ls -ald /var/www/localhost/webroot/ | grep ^l
lrwxrwxrwx 1 www-data www-data 15 2014-01-03 13:45 media -> ../static/media
lrwxrwxrwx 1 root root 13 2014-02-24 13:47 var -> ../static/var
$ rsync -qrR . /var/www/localhost/webroot/
$ ls -ald /var/www/localhost/webroot/ | grep var
drwxr-xr-x 3 root root 4096 2014-02-24 13:52 /var/www/localhost/webroot/var
So you see the symlink is no longer a symlink – the files were copied to the wrong place!
rsync also has the --no-implied-dirs option, that superficially seems to do what I want, but it only works as I intend when not doing a recursive rsync, so I have to:
find . -type f -print0 | xargs -0I rsync -R --no-implied-dirs /var/www/localhost/webroot/
Is there any more direct way to accomplish this mirroring of files without wiping out intermediate symlink directories (with or without rsync)?
rsync symlink mirror
rsync symlink mirror
edited 11 hours ago
palacsint
16117
16117
asked Feb 24 '14 at 21:04
kojiro
2,44911827
2,44911827
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
up vote
42
down vote
accepted
Use rsync's option -K (--keep-dirlinks). From the manpage:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.
add a comment |
up vote
15
down vote
I wanted to preserve my symlinks as symlinks. For that you can use the -l option.
-l, --links copy symlinks as symlinks
Since I was copying frameworks on OS X, I found this helpful.
add a comment |
up vote
2
down vote
As a non-rsync answer, the tar utility can perform this task. Use two instances of tar on either side of a pipe, the first to consume a directory structure and the second to extract it elsewhere. File ownership of the copy will likely change, while the permission modes will likely remain unchanged.
Many examples exist and I found the suggestions in this answer relatively quickly: https://unix.stackexchange.com/a/59108/34251.
Edit
A second (more succinct?) example: https://unix.stackexchange.com/a/19824/34251.
add a comment |
up vote
1
down vote
Please use -a, as it implies -l as was supposed above. But it also contains other important options if you want a complete copy of the source.
Also: As I understand the man page, -K is meant for symlinks on the receiver side. I don't think this should be the correct answer here.
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
42
down vote
accepted
Use rsync's option -K (--keep-dirlinks). From the manpage:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.
add a comment |
up vote
42
down vote
accepted
Use rsync's option -K (--keep-dirlinks). From the manpage:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.
add a comment |
up vote
42
down vote
accepted
up vote
42
down vote
accepted
Use rsync's option -K (--keep-dirlinks). From the manpage:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.
Use rsync's option -K (--keep-dirlinks). From the manpage:
-K, --keep-dirlinks
This option causes the receiving side to treat a
symlink to a directory as though it were a real
directory, but only if it matches a real directory from
the sender. Without this option, the receiver’s
symlink would be deleted and replaced with a real
directory.
For example, suppose you transfer a directory foo that
contains a file file, but foo is a symlink to directory
bar on the receiver. Without --keep-dirlinks, the
receiver deletes symlink foo, recreates it as a
directory, and receives the file into the new
directory. With --keep-dirlinks, the receiver keeps
the symlink and file ends up in bar.
One note of caution: if you use --keep-dirlinks, you
must trust all the symlinks in the copy! If it is
possible for an untrusted user to create their own
symlink to any directory, the user could then (on a
subsequent copy) replace the symlink with a real
directory and affect the content of whatever directory
the symlink references. For backup copies, you are
better off using something like a bind mount instead of
a symlink to modify your receiving hierarchy.
See also --copy-dirlinks for an analogous option for
the sending side.
answered Feb 24 '14 at 21:22
angus
9,05113332
9,05113332
add a comment |
add a comment |
up vote
15
down vote
I wanted to preserve my symlinks as symlinks. For that you can use the -l option.
-l, --links copy symlinks as symlinks
Since I was copying frameworks on OS X, I found this helpful.
add a comment |
up vote
15
down vote
I wanted to preserve my symlinks as symlinks. For that you can use the -l option.
-l, --links copy symlinks as symlinks
Since I was copying frameworks on OS X, I found this helpful.
add a comment |
up vote
15
down vote
up vote
15
down vote
I wanted to preserve my symlinks as symlinks. For that you can use the -l option.
-l, --links copy symlinks as symlinks
Since I was copying frameworks on OS X, I found this helpful.
I wanted to preserve my symlinks as symlinks. For that you can use the -l option.
-l, --links copy symlinks as symlinks
Since I was copying frameworks on OS X, I found this helpful.
answered May 29 '15 at 18:12
Ben Flynn
26837
26837
add a comment |
add a comment |
up vote
2
down vote
As a non-rsync answer, the tar utility can perform this task. Use two instances of tar on either side of a pipe, the first to consume a directory structure and the second to extract it elsewhere. File ownership of the copy will likely change, while the permission modes will likely remain unchanged.
Many examples exist and I found the suggestions in this answer relatively quickly: https://unix.stackexchange.com/a/59108/34251.
Edit
A second (more succinct?) example: https://unix.stackexchange.com/a/19824/34251.
add a comment |
up vote
2
down vote
As a non-rsync answer, the tar utility can perform this task. Use two instances of tar on either side of a pipe, the first to consume a directory structure and the second to extract it elsewhere. File ownership of the copy will likely change, while the permission modes will likely remain unchanged.
Many examples exist and I found the suggestions in this answer relatively quickly: https://unix.stackexchange.com/a/59108/34251.
Edit
A second (more succinct?) example: https://unix.stackexchange.com/a/19824/34251.
add a comment |
up vote
2
down vote
up vote
2
down vote
As a non-rsync answer, the tar utility can perform this task. Use two instances of tar on either side of a pipe, the first to consume a directory structure and the second to extract it elsewhere. File ownership of the copy will likely change, while the permission modes will likely remain unchanged.
Many examples exist and I found the suggestions in this answer relatively quickly: https://unix.stackexchange.com/a/59108/34251.
Edit
A second (more succinct?) example: https://unix.stackexchange.com/a/19824/34251.
As a non-rsync answer, the tar utility can perform this task. Use two instances of tar on either side of a pipe, the first to consume a directory structure and the second to extract it elsewhere. File ownership of the copy will likely change, while the permission modes will likely remain unchanged.
Many examples exist and I found the suggestions in this answer relatively quickly: https://unix.stackexchange.com/a/59108/34251.
Edit
A second (more succinct?) example: https://unix.stackexchange.com/a/19824/34251.
edited Apr 13 '17 at 12:36
Community♦
1
1
answered Feb 25 '14 at 10:41
crw
1679
1679
add a comment |
add a comment |
up vote
1
down vote
Please use -a, as it implies -l as was supposed above. But it also contains other important options if you want a complete copy of the source.
Also: As I understand the man page, -K is meant for symlinks on the receiver side. I don't think this should be the correct answer here.
add a comment |
up vote
1
down vote
Please use -a, as it implies -l as was supposed above. But it also contains other important options if you want a complete copy of the source.
Also: As I understand the man page, -K is meant for symlinks on the receiver side. I don't think this should be the correct answer here.
add a comment |
up vote
1
down vote
up vote
1
down vote
Please use -a, as it implies -l as was supposed above. But it also contains other important options if you want a complete copy of the source.
Also: As I understand the man page, -K is meant for symlinks on the receiver side. I don't think this should be the correct answer here.
Please use -a, as it implies -l as was supposed above. But it also contains other important options if you want a complete copy of the source.
Also: As I understand the man page, -K is meant for symlinks on the receiver side. I don't think this should be the correct answer here.
edited Nov 6 '16 at 13:30
Thomas
3,65141225
3,65141225
answered Nov 6 '16 at 13:00
Christian Gut
111
111
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f116775%2fhow-to-copy-directory-structure-without-removing-symlinks%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password