Below is the directory syncing script that I use to keep my sources
synchronized between my local machine and a remote machine. In order
to use it, you'll need to do at least two things:
1) Set REMOTE_SRC, LOCAL_SRC, and RSYNC_PATH to values appropriate
for your situation.
REMOTE_SRC should be of the form HostName:Path, where ``HostName''
is the name of the remote machine that you're syncing with and
``Path'' is the path (on the remote machine) to the directory
being sync'd.
LOCAL_SRC should be a pathname to a directory accessible via your
local machine. (Note that Samba or NFS mounts are okay.)
RSYNC_PATH should be the complete path to the rsync program on the
remote machine. (On some of the machines I use, rsync is either
located in a definitely non-standard place or else is so out of
date that I've built my own version and installed it in ~/bin.)
2) Name it something appropriate, make sure it's executable, and
place it in a directory on your PATH.
E.g, I have one called sync-sourceware which syncs my checked-out
gdb sources from sourceware.cygnus.com with these same sources
on one of the remote machines that I frequently use in Sunnyvale.
I have other scripts which sync between my laptop and my desktop
machines at home, etc. The only difference between these scripts
is the settings of the three variables mentioned in (1) above.
It uses SSH as a secure transport. Since (at least) two rsyncs are
done, this would normally require entering your passphrase as many
times as rsync is invoked. In order to avoid bothering the user to
enter passphrase after passphrase, it attempts to use an existing
ssh-agent. If none exists, it will create an agent and then invoke
ssh-add which prompts you for your passphrase. Thus, you'll be
prompted for the passphrase which unlocks your RSA key at most once.
--- sync-sources ---
#!/usr/bin/perl -w
$REMOTE_SRC = "remote.host.com:/path/to/remote/sources";
$LOCAL_SRC = "/path/to/local/sources";
$RSYNC_PATH = "/path/to/remote/rsync";
$ENV{RSYNC_RSH} = 'ssh';
my $nuke_agent = 0;
if (!$ENV{SSH_AGENT_PID}) {
my $agentdata = `ssh-agent -s`;
die "Problem starting ssh-agent" if (!defined($agentdata));
my ($agent_pid) = $agentdata =~ /^SSH_AGENT_PID=([^;]*);/m;
my ($agent_sock) = $agentdata =~ /^SSH_AUTH_SOCK=([^;]*);/m;
die "Can't fetch ssh agent environment variables"
unless defined($agent_pid)
&& defined($agent_sock);
print "agent_pid=$agent_pid; agent_sock=$agent_sock\n";
$ENV{SSH_AGENT_PID} = $agent_pid;
$ENV{SSH_AUTH_SOCK} = $agent_sock;
system("ssh-add");
sleep(4);
$nuke_agent = 1;
}
if (@ARGV) {
foreach $arg (@ARGV) {
sync_dir("$REMOTE_SRC/$arg", "$LOCAL_SRC/$arg");
}
}
else {
sync_dir($REMOTE_SRC, $LOCAL_SRC);
}
system("ssh-agent -k") if $nuke_agent;
sub sync_dir {
my ($remote_src, $local_src) = @_;
my $remote_dir = $remote_src;
$remote_dir =~ s#/[^/]*$##;
my $local_dir = $local_src;
$local_dir =~ s#/[^/]*$##;
system("rsync -avuz --exclude '*~' --rsync-path=$RSYNC_PATH $remote_src $local_dir");
system("rsync -Cavuz --exclude '*~' --rsync-path=$RSYNC_PATH $local_src $remote_dir");
}
--- end sync-sources ---