Slashes and the rsync command - linux

I am trying to do something along the same lines as what is asked in this question: How do I synchronize in both directions?
However, what I can't figure out is whether or not I should add slashes to the end of the file path. Basically I'm trying to create an alias command that syncs the contents of two directories that go by the same name but are on two different servers. What I don't want is for one directory to be copied into the other (which I am aware is a possibility depending on how the slashes at the end are done).
What I have currently is:
alias syncDirectories1 = 'rsync -tvur name#host:/Users/me/directory/ /Users/me/directory/'
alias syncDirectories2 = 'rsync -tvur /Users/me/directory/ name#host:/Users/me/directory/'
For what I am trying to accomplish, should there be slashes at the end of both file paths?

It's described in the rsync(1) manpage:
A trailing slash on the source changes this behavior to avoid creating an additional directory level at the destination. You can think of a
trailing / on a source as meaning "copy the contents of this directory" as opposed to "copy the directory by name", but in both cases the
attributes of the containing directory are transferred to the containing directory on the destination. In other words, each of the following commands copies the files in the same way, including their setting of the attributes of /dest/foo:
rsync -av /src/foo /dest
rsync -av /src/foo/ /dest/foo
As to the destination, I don't think it has any major consequences. There is a difference if the source is a file and destination doesn't exist — this will make a copy of SRC called DEST:
rsync SRC DEST
, whereas, this will create directory DEST and copy the SRC file into it:
rsync SRC DEST/

I tested it with rsync 3.1.3 on Arch Linux, the results are below:
1. rsync -avPzu test login#remote:/home/login/test "test" directory is copied inside of existing "test" on remote (structure is then test/test/...)
2. rsync -avPzu test login#remote:/home/login/test/ same as above
3. rsync -avPzu test/ login#remote:/home/login/test content of "test" directory is synchronized with the remote "test" directory
4. rsync -avPzu test/ login#remote:/home/login/test/ same as above
5. rsync -avPzu test login#remote:/home/login/ same as above
6. rsync -avPzu test login#remote:/home/login same as above
The methods 3-6 are the correct ones in this case, contrary to the accepted answer.

keep the slashes on the source, and remove them from the destination.
Like this:
alias syncDirectories1 = 'rsync -tvur name#host:/Users/me/directory/ /Users/me/directory'
alias syncDirectories2 = 'rsync -tvur /Users/me/directory/ name#host:/Users/me/directory'

I had different results from accepted answer on Ubuntu 17.04. It seems that the destination / does not have an effect.
I did the following four commands:
rsync -av src nslash # No slashes on either src or dest
rsync -av src dslash/ # Slash on Dest only
rsync -av src/ sslash # Slash on src only
rsync -av src/ sdslash/ # Slash on both src and dest
Conclusions:
once there is a / on the src, then the contents of the src only will be copied over to the dest, regardless of whether the dest has a slash or not.
no slash on the src, then the src and its content will be copied to dest.
Slashes on dest has no effect.

Related

Rsync - How to ignore for one of same name folder

I have two folders
frontend/static/
static/
I want to rsync first folder but want to ignore second folder
rsync -av --delete --exclude-from 'rsync_exclude.txt'
I write in rsyng_exclude.txt
static
igonore both
or
./static/
ignore neither.
Is there any method to ignore only static/ and rsync frontend/static/

trying to create a file structure with relative path

I'm trying to create a file structure in unix using the relative path, however the directories are being created under my current directory? What am i doing wrong.
mkdir ../folder1 -p folder2/folder3 folder2/folder4 folder5
.. goes back to my home and /folder should go into folder1, but all of this is being done my current directory?
All the filename arguments to mkdir are simply directories to create, they're not interpreted relative to each other. Putting ../folder1 first doesn't make it use that as the starting directory for all the rest.
You can use brace expansion to concatenate all the subdirectory paths to a single directory prefix.
mkdir -p ../folder1/{folder2/{folder3,folder4},folder5}
Also, remember that options usually go before filename arguments.

Rsync / Linux : prevent new directory being created inside destination directory

Pardon my novice-ness, please.
A question regarding the usage of Rsync.
If I specify, as an example, this command:
rsync -av Downloads Downloads2
the result is that the directory "Downloads2" is created with "Downloads" as a subdirectory, and, within /Downloads2/Downloads are all of the contents of the original /Downloads directory.
I am wondering if there is an option which will cause rsync to copy the contents of /Downloads to /Downloads2 without creating the /Downloads2/Downloads structure?
As you can see from "man rsync", adding a trailing slash on the source directory will prevent that directory being created:
rsync -avz foo:src/bar/ /data/tmp
A trailing slash on the source changes this behavior to avoid creating
an additional directory level at the destination. You can think of a
trailing / on a source as meaning "copy the contents of this directory"
as opposed to "copy the directory by name", but in both cases the
attributes of the containing directory are transferred to the contain‐
ing directory on the destination. In other words, each of the follow‐
ing commands copies the files in the same way, including their setting
of the attributes of /dest/foo:
rsync -av /src/foo /dest
rsync -av /src/foo/ /dest/foo

rsync NOT changed file

It is possible to rsync file even if it wasn't changed.
Let say I have file on src, and the same file on dest
when I do "rsync src dest" I want to force to download some specific file even if it is the same( have the same size, timestamp etc.)
Is this possible? --include doesn't work is there some other option for this?
Try this:
$ rsync --whole-file --modify-window=-1 src dest
--modify-window=-1 tricks rsync into believing the timestamps of the files differ even when they don't.
--whole-file makes sure entire files are copied.
Assuming src and dest are directories, a complete command to test it might look like:
$ rsync -a -v --progress --whole-file --modify-window=-1 src dest
Run it twice to verify it copies everything every time.
try the cp -R command, this copies really everything.
rsync is designed to save bytes to be transferred by transferring the different files only.
If the requirement is only to recopy same file then you can use
scp src dest

How to RSYNC a single file?

Currently i only RSync-ing the Directories as like:
* * * * * rsync -avz /var/www/public_html/images root#<remote-ip>:/var/www/public_html
So how do i rsync one single file like, /var/www/public_html/.htaccess ?
You do it the same way as you would a directory, but you specify the full path to the filename as the source. In your example:
rsync -avz --status=progress /var/www/public_html/.htaccess root#<remote-ip>:/var/www/public_html/
As mentioned in the comments: since -a includes recurse, one little typo can make it kick off a full directory tree transfer, so a more fool-proof approach might to just use -vz, or replace it with -lptgoD.
Basic syntax
rsync options source destination
Example
rsync -az /var/www/public_html/filename root#<remote-ip>:/var/www/public_html
Read more
Michael Place's answer works great if, relative to the root directory for both the source and target, all of the directories in the file's path already exist.
But what if you want to sync a file with this source path:
/source-root/a/b/file
to a file with the following target path:
/target-root/a/b/file
and the directories a and b don't exist?
You need to run an rsync command like the following:
rsync -r --include="/a/" --include="/a/b/" --include="/a/b/file" --exclude="*" [source] [target]
To date, two of the answers aren't quite right, they'll get more than one file, and the other isn't as simple as it could be, here's a simpler answer IMO.
The following gets exactly one file, but you have to create the dest directory with mkdir. This is probably the fastest option:
mkdir -p ./local/path/to/file
rsync user#remote:/remote/path/to/file/ -zarv --include "filename" --exclude "*" ./local/path/to/file/
If there is only one instance of file in /remote/path, rsync can create directories for you if you do the following. This will probably take a little more time because it searches more directories. Plus it's will create empty directories for directories in /remote/path that are not in ./local
cd ./local
rsync user#remote:/remote/path -zarv --include "*/" --include "filename" --exclude "*" .
Keep in mind that the order of --include and --exclude matters.
Aside from the good above answers, rsync expects the destination to be a directory and not a filename. Suppose you are copying the word list file words to /tmp, don't do this:
rsync -az /user/share/dict/words /tmp/words # does not work
'cp' is tolerant of this form, but rsync isn't - it will fail because it doesn't see a directory at /tmp/words. Snip off the destination filename and it works:
rsync -az /user/share/dict/words /tmp
Note that rsync won't let you change the filename during the copy, and cp will.

Resources