Execute rsync command over ssh with an ssh agent via crontab

Your cron session shell has no knowledge of the ssh agent, so can't talk to it.

When the agent is started, you can put the information needed for the agent someplace for the cron session to pick up.

Example:

AGENT="ssh-agent -s"
if [ ! -d $HOME/.ssh/agent ]; then
        mkdir -p $HOME/.ssh/agent
fi
#
# Start an agent if there isn't one running already.
#
pid=`ps -u$LOGNAME | grep ssh-age | awk '{print $1}'`
if [ -z "$pid" ]; then
        $AGENT | grep -v echo > $HOME/.ssh/agent/$HOST & pid=$!
        sleep 1 # Let it fork and stuff
fi

Then add your key to the agent.

ssh-add $HOME/.ssh/id_dsa

Now your cron job should do this before attempting to use ssh:

#
# Get our parent to pick up the required SSH env vars.
#
. $HOME/.ssh/agent/$HOST

...after which, the ssh session should proceed normally.


keychain is what you need! Just install it and add the follow code in your .bash_profile (or equivalent):

if [ -x /usr/bin/keychain ]; then
  /usr/bin/keychain --quiet --clear $HOME/.ssh/id_rsa
fi

For config.fish (2):

if not status --is-interactive
   keychain --eval --quiet --quick $HOME/.ssh/id_rsa
end

Then use the code below in your script to load the ssh-agent environment variables:

. ~/.keychain/`/bin/hostname`-sh

For Fish:

source $HOME/.keychain/(hostname)-fish

If your key have a passhphrase, keychain will ask you once (valid until you reboot the machine or kill the ssh-agent).

Note: keychain also generates code to csh and fish shells, so just replace the suffix "-sh" to "-csh" or "-fish".


I suppose you're using key based auth to authenticate yourself with the remote machine. Try the line below:

rsync -av --delete -e "ssh -i .ssh/id_rsa" mydir [email protected]:~/backupDir

Where .ssh/id_rsa is the path to your private key. This is the exact line I'm using to do my backups and it always works fine for me.

Best wishes,
Fabian


I don't have enough rep to vote up the first answer, but it solved the issue that I was having. In terms of ssh-agent, you may already have one running. Here's a script to extract the SSH_AGENT_PID & SSH_AUTH_SOCK from the environment without any additional stuff to save on startup of ssh-agent. (Assumes that you have perl)

Put the following in a script. (for example findagent.pl)

and inside your cron script add the line:

eval `{path to script}/findagent.pl`


\#!/usr/bin/perl -w
use strict;
my $agents = `ls -tr /tmp/ssh-*/*`;
my @agents;
(@agents) = split/\n/,$agents;

my $sshpid = `ps aux|grep ssh-agent|grep -v grep|awk '{print \$2}'|head -1`;
chomp($sshpid);
my @parts;
for (@agents) {
  chomp($_);
  if (!$_) { next; }
  my $agentfile = $_;
  (@parts) = split/\./,$agentfile;
  my $masterpid = `ps aux|grep $parts[1]|grep enlightenment`;
  if ($agentfile =~ m/$parts[1]/) {
    my $line1 = "SSH_AUTH_SOCK=" . $agentfile . '; export SSH_AUTH_SOCK';
    my $line2 = 'SSH_AGENT_PID=' . $sshpid . '; export SSH_AGENT_PID;';
    my $line3 = 'echo Agent pid ' . $sshpid . ';';
    print("$line1\n$line2\n$line3\n");
    last;
  } else {
    next;
  }
}