【问题标题】:git push not working inside a cron jobgit push 在 cron 作业中不起作用
【发布时间】:2025-11-25 22:25:01
【问题描述】:

我目前正在清理别人在 CentOS 6 服务器上留下的烂摊子。有一个应用程序需要每 6 小时备份到一个 github 帐户。有一个脚本负责准备数据,它负责 git add 和 git commit。

git push 由“expect”脚本处理。这样做是为了在 ssh 请求时可以将密码短语传递给 git push。用户不想使用空密码。

脚本在 root 用户从 bash shell 中的命令行运行时运行良好。我可以看到传输到github的文件。

当脚本在由 root 创建的 crontab 下运行时,脚本似乎在运行,但 git push 不会发生。如果我手动运行 git push,在脚本失败后,我注意到应该发生的推送与我从命令行调用的手动推送一起发生。看来脚本中应该发生的推送已经被缓存了,没有推送到github。

谁能建议我在这里缺少什么?是否有可能让 git push 在这样的脚本中工作?

问候

理查德

【问题讨论】:

  • 当您手动执行命令时,您会以 root 身份运行它吗?不是须藤?
  • 命令在 cron 下失败的通常原因是它取决于 .profile 中设置的环境变量,因为它不是由 cron 作业运行的。
  • 当我手动运行命令时,我以 root 身份运行它
  • 我同意环境变量可能是从 cronjob 运行命令失败的原因。在标准的 CentOS 安装中,似乎没有为 root 登录设置很多环境变量。我遇到问题的脚本中的所有命令都使用它们的绝对路径调用,并且不依赖于 PATH 变量。

标签: git bash github cron


【解决方案1】:

问题应该是当 git push 尝试运行时,ssh-agent 没有正确地将密码短语传递给 ssh。

follow-up blog post 所示,您不能简单地在 cron 中调用 ssh-agent -s,否则它会简单地创建另一个实例,其中没有密钥。

为了解决这个问题,我需要找到一种方法来避免启动另一个 ssh-agent 进程,而是每次登录时都可以访问海马启动。
我对我的 crontab 进行了更改,它将搜索现有的 ssh-agent 进程 ID 和身份验证套接字并将它们导入到 cron 环境中。这是一种 hack,但它确实有效(不像上次那样)。
只需在尝试连接到您的 SSH 服务器之前将以下内容添加到您的脚本中(或者按照我所做的将它们直接放入 cron 作业中,用分号分隔):

export SSH_AGENT_PID=`ps -a | grep ssh-agent | grep -o -e [0-9][0-9][0-9][0-9]`
export SSH_AUTH_SOCK=`find /tmp/ -path '*keyring-*' -name '*ssh*' -print 2>/dev/null` 

澄清一下:

只需将以下内容添加到您的脚本中

这意味着上面两行是声明为 cron 作业并由该 cron 作业调用的脚本的一部分。

将它们直接放入 cron 作业中,用分号分隔

如果脚本足够小,您可以完全摆脱脚本并让您的 cron 作业成为一系列命令:请参阅“Run two commands with a crontab”。

crontab -l | { cmd1; cmd2 ; cmd3; } | crontab -

这种语法只是add programmatically a command to a cron job 的一种方式。

【讨论】:

  • 难道不能通过设置rc-script 来改善这种情况,该脚本将在启动时运行openvt -c 8 /bin/sh -c 'umask 077; ssh-agent -s >/root/agent.env && source /root/agent.env && ssh-add /path/to/the/key' 之类的东西,然后cron作业脚本将在尝试连接之前只是source /root/agent.env服务器?
  • @kostix 这听起来像是一个很好的改进。你测试了吗?
  • 不,我自己会使用一个受到良好保护的 decrypted 密钥。但是,如果 OP 想要/需要输入密码,专用的开机设置对我来说似乎是一件好事。顺便说一句,我的评论并不是为了改善您的答案,而是试图为 OP 提供一些新的想法。
  • @kostix 我明白了。让我们看看 OP 对此有何看法。
  • 答案不充分,也没有解释如何“将它们直接放入 cron 作业中”,用分号分隔。在哪里?对在哪里?在一行中输入相同的命令?就在 cronjob 的开头?我们无法理解“就在那儿”是什么意思