通过PHP exec IIS执行git pull

12

这是我遇到过的最难以诊断的问题。我似乎无法调用:

exec('call git pull', $output);
进程挂起,并且往往会带着 IIS 一起挂掉。
exec('call git status', $output); //works fine

这是我所做的:

  • 生成了添加到 Github 的 RSA 密钥(密码为空)
  • 每个人都对 mysite/.git/Program Files/git/bincmd.exe 有权限
  • 尝试使用其他帖子中提到的修复“斜杠”问题的 SSL 证书方法
  • 尝试使用 https:// 而不是 SSH
  • 尝试将标准错误输出重定向到 2>NUL2>&1

显然,这里存在一个许可问题,即 exec 调用了 cmd.exe,然后调用 git.exe,然后调用 sh.exe 来连接 GitHub,然后使用 git-pull 和可能的 git-send-pack 等。

我猜测 'sh.exe' 确定当前用户为 IUSR 并且找不到要进行身份验证的 RSA 密钥。

如果我能弄清楚如何对 IUSR 帐户进行 ssh-keygen,我就会尝试那样做。

如果我能弄清楚如何通过 exec git bash 而不是 git(通过 cmd.exe),我就会尝试那样做。

问题的基本形式如下:

如何通过 PHP 的 exec 方法从我的 Github 存储库中拉取数据?

问题似乎肯定与 SSH 有关,但我已经尝试了所有可以想到的方法。

请帮帮我!


为什么你在使用call git pull而不是仅仅使用git pull呢? - gustavotkg
调用只是使用exec()的“推荐”方法,就像我读到的那样-我尝试了两种方法,没有明显的区别。 - rmirabelle
我相信你可能遇到了写入权限的问题。如果你考虑一下git status和git pull之间的区别,一个显示有关存储库的信息,而另一个实际上会进行文件系统级别的更改。 - Kevin
是的,看起来确实是权限问题,但正如问题所述,我已经尝试了我能想象到的最宽松的权限,但仍然无济于事。 - rmirabelle
10个回答

15

今天我也遇到了同样的问题,用进程监视器查看发现sh.exe在某些情况下会在C:\Windows\SysWOW64\config\systemprofile\.ssh中寻找密钥。因此,我将C:\Users\Administrator\.ssh文件夹中的所有内容复制到该文件夹中,然后它就可以正常工作了。


1
胜利了!我还得为这个目录提供明确的权限,但它现在确实有效了。奇迹发生了,拯救了这一天,让世界变得更美好,奖励已颁发。 - rmirabelle
你是怎么发现的? - Petah
2
我还想补充一点,就是在它能够正常工作之前,你必须给IUSR用户读取新创建文件夹的权限 :) - ZorleQ
太棒了!你是我的救星… :) 谢谢。 - reignsly
正在运行Windows Server 2012,但它无法解决我的问题。我可以执行git status命令,但无法执行git pull命令。您如何检查sh.exe是否已查找到密钥? - Tarun Gupta
显示剩余3条评论

2
我正在运行Windows Server 2012,但无法使Iamz的解决方案生效。我在我的C:\中搜索了“.ssh”,并发现另外一个.ssh文件夹位于C:\Program Files (x86)\Git\.ssh。我将C:\Users\Administrator\.ssh文件夹下所有内容复制到这个文件夹中,并设置了允许IUSR访问的权限,一切都很顺利。

对我不起作用,我可以执行git status但无法执行git pull。 - Tarun Gupta

1

有许多 PHP Git 库/工具。 https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#git-php

个人一直在使用 GLIP(PHP 中的 Git 库) http://fimml.at/#glip

我在 GitHub 上有一个源代码分支,我添加了一个存档功能。 基本上,我动态创建一个 Git 命令,并使用 PHP 的 passthru 方法来调用它。 也许查看我的代码可以给您一些启示。这是提交记录 https://github.com/fontvirus/glip/commit/89127f7f9a4dc61697929f36684533406f348ffe


1
将您的 .ssh 文件夹移动到用户配置文件目录。您可以在全局变量 $_SERVER['USERPROFILE'] 中看到您的应用程序配置文件目录。在我的情况下,它是 C:\Windows\system32\config\systemprofile。 然后为用户授予读/写此文件夹 (.ssh) 的权限:IIS_IUSRS、IUSR。

0

对于Iamz的解决方案的另一种变体是使用目录C:\Windows\System32\config\systemprofile\.ssh

我通过在我的IIS服务器上运行以下脚本得出这个结论,该脚本立即指出C:\Windows\System32\config\systemprofile\.ssh丢失了(请根据您的机器设置$path_of_git和$path_to_repo):

<?php
$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w"),  // stderr
);
$path_of_git = 'c:\\path\\to\\git';
$path_to_repo = 'C:\\inetpub\\repo';
$process = proc_open($path_of_git.' fetch', $descriptorspec, $pipes, $path_to_repo, null);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
echo '<pre>'.htmlspecialchars($stdout).'</pre>';
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
echo '<pre style="color:red;">'.htmlspecialchars($stderr).'</pre>';
echo '<p>return value=' . proc_close($process) . '</p>';
?>

尽管如此,我仍然受到权限问题的困扰,因此在每个git命令之前,我发现将 HOME 声明为IUSR可以轻松访问的其他位置非常有用,并使用git sh执行整个过程。例如:

\pathToGit\bin\sh -c "export HOME='/c/somewhereIUSRCanGetTo/';git fetch"

其中C:\somewhereIUSRCanGetTo\.ssh\包含私钥和allowed_hosts文件。


0

今天早些时候我遇到了这个问题,并以不同的方式解决了它。

我的问题是IUSR没有一个家目录来放置ssh密钥或git凭据文件。

我创建了一个.sh文件,在调用git之前更改了HOME变量,将我的密钥放在正确的位置,就好像那是它的家目录一样,然后使用sh.exe运行.sh文件。

#!/bin/bash
export HOME="/c/some/location"
git pull

0

你需要使用proc_open,因此可能会遇到权限相关的问题。

这是我使用的脚本

<?php

//error_reporting(E_ALL);
ignore_user_abort(true);

function syscall ($cmd, $cwd) {
    $descriptorspec = array(
        1 => array('pipe', 'w'), // stdout is a pipe that the child will write to
    );
    $resource = proc_open($cmd, $descriptorspec, $pipes, $cwd);
    if (is_resource($resource)) {
        $output = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        proc_close($resource);
        return $output;
    }
}

// GitHub will hit us with POST (http://help.github.com/post-receive-hooks/)
if (!empty($_POST['payload'])) {

    // pull from master
    $result = syscall('git pull', '/var/www/example.com');

    // send us the output
    mail('team@example.com', 'GitHub hook `git pull` result', $result);

    // clear APC
    if (apc_clear_cache('opcode') == false) {
        mail('root', 'Unable to apc_clear_cache()', '');
    }

}

?>

也许这份指南可以帮到你:http://technotes.tumblr.com/post/33867325150/php-hook-script-that-can-git-pull-apc-clear-cache - webjay
奇怪而糟糕的是,这个脚本与我的现有代码完全一样地失败了 :-( - rmirabelle

0

我不太确定Windows环境

但主要问题是".php文件"调用exec命令时没有管理员权限(或*NIX操作系统中的root)

在我的环境中,我将该文件的所有权更改为root特权(如sudo)。另一种方法是创建新的用户组,拥有777权限,并将该文件分配给该用户组所拥有的用户

希望这可以帮到你


0
我能够在这里的帮助下部分地让它工作。我运行了一个批处理脚本,其中运行了以下命令:
ssh-agent -s ssh-add -l
以查看我有哪些密钥。在运行这些命令之前,我将HOME=/c/Users/Username环境变量设置为我的用户,具有正确的ssh密钥。(我使用unix路径,因为我是在Git Bash中运行它)

0

您需要直接向cmd.exe授予权限。根据Windows版本和应用程序池设置的方式,可能是IIS_IUSR、IUSR和/或NETWORK SERVICE。将具有完全权限的用户添加到cmd.exe。

当然,我不建议这样做,因为它会直接影响安全。话虽如此,在Windows中我没有找到其他实现方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接