为什么post-merge钩子无法配合cronjob正常工作?
我在staging服务器上使用cronjob保持代码仓库及编译后的资源处于最新状态,所用cronjob命令如下:
* * * * * cd ~/public_html/ && git reset --hard && git pull
.git/hooks/post-merge钩子内容:
#!/usr/bin/env bash sh compile.sh
钩子权限信息:
7494392 -rwxr-xr-x 1 admin admin 34 Jan 30 17:44 post-merge
compile.sh脚本:
#!/bin/sh cd assets && gulp dev
该钩子通过SSH命令行手动执行时可正常运行,但通过cronjob执行时无法触发,求解决方向。
补全环境变量
cron的执行环境比交互式Shell精简很多,PATH通常不包含git、gulp等工具的路径。可以在钩子顶部添加环境变量配置,比如:export PATH=/usr/local/bin:/usr/bin:$PATH或者直接使用工具的绝对路径,比如把
git换成/usr/bin/git,gulp换成./node_modules/.bin/gulp(如果是项目本地安装)。全部改用绝对路径
相对路径在cron环境下可能无法正确解析:- 将钩子中的
sh compile.sh改为sh /home/admin/public_html/compile.sh - 将
compile.sh中的cd assets改为cd /home/admin/public_html/assets - 确保gulp命令使用绝对路径
- 将钩子中的
确认git pull是否触发了merge
post-merge钩子仅在git pull实际执行合并操作时才会触发,如果仓库已是最新状态,git pull不会触发钩子。可以修改远程仓库内容,触发一次真实的合并,再观察cron执行后的结果。也可以在cron命令末尾手动调用钩子,验证其在cron环境下是否能运行:* * * * * cd /home/admin/public_html/ && git reset --hard && git pull && ./.git/hooks/post-merge添加日志排查错误
在钩子和脚本中加入日志输出,定位问题点:
修改post-merge:#!/usr/bin/env bash echo "post-merge触发时间: $(date)" >> /home/admin/public_html/hook_run.log sh /home/admin/public_html/compile.sh >> /home/admin/public_html/hook_run.log 2>&1修改
compile.sh:#!/bin/sh echo "compile.sh执行时间: $(date)" >> /home/admin/public_html/compile_run.log cd /home/admin/public_html/assets && /usr/local/bin/gulp dev >> /home/admin/public_html/compile_run.log 2>&1执行后查看日志,是否有命令找不到、路径不存在等错误提示。
检查cron执行用户
确保cron以admin用户执行(钩子权限归属admin),可以用crontab -u admin -e编辑cron任务,或者在命令前指定用户:* * * * * su - admin -c "cd /home/admin/public_html/ && git reset --hard && git pull"重新确认钩子权限与shebang
再次执行chmod +x .git/hooks/post-merge确保可执行权限生效,同时用which bash确认bash路径,将钩子的shebang替换为绝对路径,比如#!/bin/bash(根据实际路径调整)。
内容的提问来源于stack exchange,提问作者John Doe

