у меня есть cronjob:
0 9 * * * rsync -a mydir remote_machine:
Я установил это с помощью crontab -e. У меня запущен ssh-agent, и когда я выполняю команду rsync, она работает без какого-либо взаимодействия с пользователем или ввода пароля, но cronjob не работает со следующим сообщением:
Date: Wed, 9 Dec 2009 11:11:00 -0600 (CST)
From: Cron Daemon <me@my_machine.my_domain>
To: me@my_machine.my_domain
Subject: Cron <me@my_machine> rsync -a /home/me/mydir remote_machine:
Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,gssapi-with-mic,password).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at /SourceCache/rsync/rsync-35.2/rsync/io.c(452)
[sender=2.6.9]
почему это не работает? Я знаю, что cronjobs запускаются со мной как пользователем (если я запускаю '* * * * * touch / tmp / a', я владею файлом), поэтому я предполагаю, что rsync входит в систему как я, используя мой закрытый ключ ...
Брелок это то, что вам нужно! Просто установите его и добавьте следующий код в свой .bash_profile
(или эквивалент):
if [ -x /usr/bin/keychain ]; then
/usr/bin/keychain --quiet --clear $HOME/.ssh/id_rsa
fi
Для config.fish (2):
if not status --is-interactive
keychain --eval --quiet --quick $HOME/.ssh/id_rsa
end
Затем используйте приведенный ниже код в своем скрипте для загрузки переменных среды ssh-agent:
. ~/.keychain/`/bin/hostname`-sh
Для рыбы:
source $HOME/.keychain/(hostname)-fish
Если в вашем ключе есть кодовая фраза, связка ключей спросит вас один раз (действует, пока вы не перезагрузите компьютер или не убьете ssh-agent).
Примечание: брелок также генерирует код для csh
и fish
оболочки, поэтому просто замените суффикс «-sh» на «-csh» или «-fish».
Оболочка сеанса cron не знает агента ssh, поэтому не может с ним разговаривать.
Когда агент запущен, вы можете поместить информацию, необходимую для агента, где-нибудь для сеанса cron.
Пример:
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
Затем добавьте свой ключ к агенту.
ssh-add $HOME/.ssh/id_dsa
Теперь ваша задача cron должна сделать это, прежде чем пытаться использовать ssh:
#
# Get our parent to pick up the required SSH env vars.
#
. $HOME/.ssh/agent/$HOST
... после чего сеанс ssh должен продолжаться нормально.
У меня недостаточно представителей, чтобы проголосовать за первый ответ, но это решило мою проблему. Что касается ssh-agent, возможно, он у вас уже запущен. Вот сценарий для извлечения SSH_AGENT_PID и SSH_AUTH_SOCK из среды без каких-либо дополнительных вещей, которые нужно сохранить при запуске ssh-agent. (Предполагается, что у вас есть Perl)
Поместите в сценарий следующее. (например findagent.pl)
и внутри вашего cron-скрипта добавьте строку:
eval `{путь к скрипту} / 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;
}
}
Я полагаю, вы используете аутентификацию на основе ключа для аутентификации на удаленном компьютере. Попробуйте следующую строку:
rsync -av --delete -e "ssh -i .ssh/id_rsa" mydir user@host.tld:~/backupDir
Где .ssh / id_rsa - это путь к вашему закрытому ключу. Это точная линия, которую я использую для резервного копирования, и она всегда хорошо работает для меня.
С наилучшими пожеланиями,
Fabian
В качестве альтернативы, вместо использования агента ssh, я заставил свой скрипт делать экспорт RSYNC_RSH = "ssh -i /home/user/.ssh/id_rsa" unset SSH_AGENT_PID unset SSH_AUTH_SOCK перед вызовом rsync. Поместив его в RSYNC_RSH вместо использования «-e ...», это упростило настройку используемого файла идентификатора в зависимости от хоста.
Надеюсь, это поможет, B