Rsync problems

I’ve tried every possibility I can think of, so this forum is my last resort. I just got a flash drive, and I want it to sync with my computer when I plug it in, so that new files on the computer go to it, and new files on it go to the drive. Right now I’ve got a folder on each computer that works as an exact duplicate of it’s pair, and I need to use rsync between them.

I can’t get rsync to work right, I’m using the format "rsync -v " & (quoted form of (POSIX path of localOrig)) & " " & (quoted form of (POSIX path of jumpBackup))
What am I doing wrong? Thanks for the help!

Hi,

first take a look at this topic.
there is described to create a launchd agent to manage the automatic backup when the stick is mounted.

You need a different script, which could look like


property Stick : "myStick" -- name of the flash drive
property jumpBackup : quoted form of ("/Volumes/" & Stick & "/Backup") -- path to the backup folder on the flash drive
property localOrig : quoted form of "/Users/myUser/path/to/folder" -- path to the local folder
property del : "--delete " -- set to a single space if files at destination shouldn't be deleted, which don't exist any more at source
property state : false

if (Stick is in (do shell script "/bin/ls /Volumes")) then
	if state is false then
		set state to true
		try
			do shell script "/usr/bin/rsync -vauE " & del & localOrig & space & jumpBackup
			do shell script "/usr/bin/rsync -vauE " & del & jumpBackup & space & localOrig
			write_log(Stick & ": Backup successfully done")
		on error e
			write_log(e)
		end try
	end if
else
	if state is true then set state to false
end if

on write_log(theMessage)
	tell (current date) to set theDate to short date string & space & time string & ": "
	set logFile to ((path to current user folder as Unicode text) & "Library:Logs:rsync_backup.log")
	try
		set the logStream to open for access file logFile with write permission
		write (theDate & theMessage & return) to logStream starting at eof as «class utf8»
		close access logStream
	on error
		try
			close access file logFile
		end try
	end try
end write_log

The script logs all activities in ~/Library/Logs/rsny_backup.log and can be watched in Console.app

Thanks StefanK, I appreciate the speedy help!

It works beautifully, you’ve solved my problem :slight_smile:

PS: For a bidirectional sync you must omit the --delete flag (set the property del to a single space character)

I figured that, I’ve got it setup as a little app that DSW (Do Something When) launches for me when my drive mounts. I love that it can work both ways, but what are the options (-vauE) attached to rsync?

from the rsync man page

-a, --archive
This is equivalent to -rlptgoD. It is a quick way of saying you
want recursion and want to preserve almost everything (with -H
being a notable omission). The only exception to the above
equivalence is when --files-from is specified, in which case -r
is not implied.

          Note that -a does not preserve hardlinks, because finding multi-
          ply-linked  files is expensive.  You must separately specify -H.

-u, --update
This forces rsync to skip any files which exist on the destina-
tion and have a modified time that is newer than the source
file. (If an existing destination file has a modify time equal
to the source file’s, it will be updated if the sizes are dif-
ferent.)

          In  the current implementation of --update, a difference of file
          format between the sender and receiver is always  considered  to
          be important enough for an update, no matter what date is on the
          objects.  In other words, if the source has  a  directory  or  a
          symlink  where  the  destination  has a file, the transfer would
          occur regardless of the timestamps.  This might  change  in  the
          future  (feel free to comment on this on the mailing list if you
          have an opinion).

-v, --verbose
This option increases the amount of information you are given
during the transfer. By default, rsync works silently. A single
-v will give you information about what files are being trans-
ferred and a brief summary at the end. Two -v flags will give
you information on what files are being skipped and slightly
more information at the end. More than two -v flags should only
be used if you are debugging rsync.

          Note that the names of the transferred files that are output are
          done using a default --out-format of  "%n%L",  which  tells  you
          just  the  name of the file and, if the item is a link, where it
          points.  At the single -v level of verbosity, this does not men-
          tion when a file gets its attributes changed.  If you ask for an
          itemized list of changed attributes (either --itemize-changes or
          adding  "%i"  to  the  --out-format setting), the output (on the
          client) increases to mention all items that are changed  in  any
          way.  See the --out-format option for more details.

-E, --extended-attributes
Apple specific option to copy extended attributes, resource
forks, and ACLs. Requires at least Mac OS X 10.4 or suitably
patched rsync.

Thanks for the help.

Two questions:
Why the two spaces after the -vauE, with the del variable as a space there are two spaces. Is that required?

Do I need to have to use "/usr/bin/rsync -vauE " or can I just use “rsync -vauE”?

Where do you see two spaces? The answer is though is no. One space or five spaces will make no difference.

As for question two adding the “/usr/bin/” in front of the command you are calling ensures your system
will find it. You are actually calling a program called ‘rsync’ that is located in the folder ‘/usr/bin/’.

If ‘/usr/bin/’ is in your $PATH then it does not matter. If you do not know what $PATH is then I suggest
leaving it.

hth,

Craig

Because I live in a PC world, I’ve had to partition my usb key with a FAT partition and an HFS partition, so I updated the script to work with both. Anyone see any problems with this?


set MountedVolumes to (do shell script "ls /Volumes")
--Now define the names of the partitions
set MacPartition to "JL Jumpdrive" -- The HFS+ partition
set PCPartition to "JLJUMP" -- The MS-DOS FAT partition
-- The locations of the partitions
set MacPartLoc to quoted form of ("/Volumes/" & MacPartition & "/WorkDocs/")
set PCPartLoc to quoted form of ("/Volumes/" & PCPartition & "/WorkDocs/")
-- The work folder
set WorkFolder to (quoted form of "/Users/Jamie/Documents/WorkDocs/")
-- The error log
set ErrLog to ""

if MountedVolumes contains MacPartition then -- Check if the HFS+ Partition is mounted
	-- Copy the updates made in the home folder on the drive
	try
		do shell script "rsync -vauE  " & MacPartLoc & " " & WorkFolder
	on error e
		set end of ErrLog to return & e
	end try
	-- Copy the changes made in the home folder
	try
		do shell script "rsync -vauE  " & WorkFolder & " " & MacPartLoc
	on error e
		set end of ErrLog to return & e
	end try
end if
if MountedVolumes contains PCPartition then -- If the MS-DOS FAT partition is mounted, it would be if the mac partition is mounted, but best to be sure
	-- Copy the updates made in the home folder on the drive
	try
		do shell script "rsync -vauE  " & PCPartLoc & " " & WorkFolder
	on error e
		set end of ErrLog to return & e
	end try
	-- Update the partition from the work folder
	try
		do shell script "rsync -vauE  " & WorkFolder & " " & PCPartLoc
	on error e
		set end of ErrLog to return & e
	end try
end if

if ErrLog = "" then
	set LogTxt to return & "All backups are completed successfully"
	set fileWrite to write_to_file(LogTxt, "Europa:Users:Jamie:Documents:Scripts:Jumpdrive:Log.txt")
	if not fileWrite then say "The file write didn't work"
else
	set LogTxt to return & "There were errors:" & return & ErrTxt
	set fileWrite to write_to_file(LogTxt, "Europa:Users:Jamie:Documents:Scripts:Jumpdrive:Log.txt")
	if not fileWrite then say "The file write didn't work"
end if

on write_to_file(this_data, target_file)
	try
		set the target_file to the target_file as string
		set the open_target_file to open for access file target_file with write permission
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
		return false
	end try
end write_to_file

Why the dual format? OS X will read/write to a FAT32 volume just fine.

I did what StefanK suggested and omitted the delete flag for the bidirectional sync. Currently, as an example, if I delete something on the flash drive and I do a sync with the computer it will put it back on the flash drive. This means that if I want to delete something I need to delete in two places before I do a sync. Is there a way to avoid this or is it just a product of the bidirectional sync and deletions will just have to be made manually in two places? I am guessing there is no way for the script to know that it was a deletion from one place and not an addition at the other.

Exactly. rsync is a one-way syncing program, using it once in each direction does not make a proper two-way sync.

A proper two-way sync needs (among other things) to keep a record of what files were in each location. If a file existed on both sides “last time” but is missing from one side now, then it can determine that the file was deleted on that one side (and should probably be deleted on the other side). If a file did not exist on either side “last time” but it is present on one side now, then it can determine that the file was added to one side (and should probably be added to the other side).

Among other things, revision control tools can do this for you, but they are usually a bit more complicated than just “run a sync”. You usually have to tell it when you are adding and deleting files (though some of that process is not needed or could be automated in some of the tools).

There are probably other tools like it, but I have previously used Unison to do two-way syncing. I was using Solaris and Linux machines at the time, but it is available for Mac OS X, too (though I have never used it on Mac OS X).