使用 ssh 代理通过 crontab 通过 ssh 执行 rsync 命令

aar*_*ron 21 rsync cron

我有一个定时任务:

0 9 * * * rsync -a mydir remote_machine:
Run Code Online (Sandbox Code Playgroud)

我用'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]
Run Code Online (Sandbox Code Playgroud)

为什么这不起作用?我知道 cronjobs 以用户身份与我一起运行(如果我运行 '* * * * * touch /tmp/a' 我拥有该文件)所以我假设 rsync 正在使用我的私钥以我的身份登录...

小智 20

钥匙扣正是您所需要的!只需安装它并在您的.bash_profile(或等效的)中添加以下代码:

if [ -x /usr/bin/keychain ]; then
  /usr/bin/keychain --quiet --clear $HOME/.ssh/id_rsa
fi
Run Code Online (Sandbox Code Playgroud)

对于 config.fish ( 2 ):

if not status --is-interactive
   keychain --eval --quiet --quick $HOME/.ssh/id_rsa
end
Run Code Online (Sandbox Code Playgroud)

然后在脚本中使用以下代码加载 ssh-agent 环境变量:

. ~/.keychain/`/bin/hostname`-sh
Run Code Online (Sandbox Code Playgroud)

对于鱼:

source $HOME/.keychain/(hostname)-fish
Run Code Online (Sandbox Code Playgroud)

如果您的密钥有密码,钥匙串将询问您一次(在您重新启动机器或杀死 ssh-agent 之前有效)。

注意:钥匙串也会生成代码 tocshfishshell,所以只需将后缀“-sh”替换为“-csh”或“-fish”。


Dav*_*osh 11

您的 cron 会话 shell 不了解 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
Run Code Online (Sandbox Code Playgroud)

然后将您的密钥添加到代理。

ssh-add $HOME/.ssh/id_dsa
Run Code Online (Sandbox Code Playgroud)

现在,您的 cron 作业应该在尝试使用 ssh 之前执行此操作:

#
# Get our parent to pick up the required SSH env vars.
#
. $HOME/.ssh/agent/$HOST
Run Code Online (Sandbox Code Playgroud)

...之后,ssh 会话应该正常进行。

  • 我所需要的只是获取 SSH_AUTH_SOCK 和 SSH_AGENT_PID 环境变量(我将它们放在 .ssh-agent 而不是 .ssh/agent/ 中)所以这就是我最终得到的结果:“0 9 * * * . $HOME/.ssh -agent &amp;&amp; rsync -av $HOME/mydir remote_machine:" (3认同)