使用 PHP 脚本作为提交后挂钩、触发 bash 脚本、执行 git-pull?

Posted

技术标签:

【中文标题】使用 PHP 脚本作为提交后挂钩、触发 bash 脚本、执行 git-pull?【英文标题】:Using a PHP script as a post-commit hook, to trigger a bash script, to do a git-pull? 【发布时间】:2012-03-22 03:47:44 【问题描述】:

这是 bash 脚本:

#!/bin/bash

echo "$NODE_ENV"
(
echo $USER;
echo $PATH;
cd /opt/chat-staging/;
git pull;
NODE_ENV=staging;
echo "Set NODE_ENV to $NODE_ENV";
node leaderboard.js & node app.js;
echo "Started leaderboard.js";
echo "Started app.js";
)
echo "NODE_ENV is now $NODE_ENV"

这是 php 脚本:

<?php

exec('/bin/bash /opt/chat-staging/start_app.sh 2>&1', &$output, &$return_var);
print_r($output);
print $return_var;

?>

我将它设置为 github 提交后挂钩,但这是输出:

数组 ( [0] => [1] => www-data [2] => /usr/bin [3] => /usr/lib/git-core/git-sh-setup: 90: sed: 未找到 [4] => basename: 写入错误:损坏的管道 [5] => /usr/lib/git-core/git-sh-setup: 212: uname: 未找到 [6] => 主机密钥验证失败。 [7] => 致命: 远端意外挂断 [8] => 将 NODE_ENV 设置为暂存 [9] => /opt/chat-staging/start_app.sh:第 11 行:节点:未找到命令 [10] => /opt/chat-staging/start_app.sh:第 11 行:节点:未找到命令 找到 [11] => 启动 leaderboard.js [12] => 启动 app.js [13] => NODE_ENV 现在是 ) 0

/opt/chat-staging/ 归“www-pub”所有;在 /etc/groups 中,我有“www-pub:x:1000:www-data,root”。

那么为什么这不起作用?我什至在 /var/www/.ssh/id_rsa 中有一个 RSA 密钥,并将公钥添加为 GitHub 部署密钥。

编辑、补充

我添加了一个 git remote -v;到脚本,就在“git pull”之前。

root@li70-243:/opt/chat-staging# su - www-data
$ bash /opt/chat-staging/start_app.sh
origin  git@github.com:zackster/CompassionPit--Node-.git (fetch)
origin  git@github.com:zackster/CompassionPit--Node-.git (push)
Already up-to-date.

而我仍然看到 PHP 输出...

数组 ( [0] => 来源 git@github.com:zackster/CompassionPit--Node-.git (fetch) [1] => origin git@github.com:zackster/CompassionPit--Node-.git (推)[2] => 大师 [3] => * 声誉 [4] => /usr/lib/git-core/git-sh-setup: 90: sed: 未找到 [5] => basename: 写入错误:管道损坏 [6] => /usr/lib/git-core/git-sh-setup: 212: uname: 未找到 [7] => /usr/lib/git-core/git-pull: 244: sed: 没有 found [8] => 您的配置指定与 ref 合并 'reputation' [9] => 来自远程,但没有获取这样的 ref。

【问题讨论】:

为什么要使用 PHP 脚本?? /var/www 不是 www-pub 和 www-data 的主目录,它们基本上没有。 从控制台手动调试 bash 脚本 - 在执行期间您有很多错误 @knittl,我使用 PHP 脚本,因为它非常简单。对我来说最少的击键次数。 @knittl 如果您能推荐一个更好、更快、更智能、更安全的解决方案 - 我将实施 那个 !我总是渴望学习 【参考方案1】:

您的 PHP 脚本似乎运行良好。 exec() 不是“工作正常”。您希望将 PATH 环境变量设置为您的常规 shell 用户设置的任何内容。它不是。您需要设置 bash 脚本(以及其中的工具)工作的环境。

你的 shell 中执行 echo $PATH 并将其添加到你的 exec 中:

exec('export PATH=/usr/bin:/usr/local/bin:/some/other/paths && /bin/bash /opt/chat-staging/start_app.sh 2>&1', &$output, &$return_var);

然后再次尝试您的脚本。您还可以将该 PATH 移动到您的 shell 脚本中。您甚至可以复制 您的 .bashrc(或 .bash_profile 或其他)并使用 source …/.bashrc 加载它。

除了exec(),您还可以查看proc_open(),通过它您可以更好地控制要执行的流程。


github 解释了如何挂钩 post 接收事件:http://help.github.com/post-receive-hooks/

【讨论】:

exec('导出路径 = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games && / bin/bash /opt/chat-staging/start_app.sh 2>&1', &$output, &$return_var); --- 现在输出 Array ( ) 2 是的,我在不应该有的地方添加了空格。 export PATH=/usr/… 而不是 export PATH = /usr/ 感谢您的帮助,这是一个非常令人沮丧的问题!

以上是关于使用 PHP 脚本作为提交后挂钩、触发 bash 脚本、执行 git-pull?的主要内容,如果未能解决你的问题,请参考以下文章

Perforce客户端预提交挂钩

哈士奇预提交挂钩未触发

将 Play Framework 标签提交到 SVN 并触发提交挂钩

在 Gitlab 中合并请求后运行 Jenkins 作业

将 Locust 作为库运行时触发事件挂钩

在 Git 中运行预提交挂钩。有没有办法验证脚本是不是正在运行?