可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Easily the most difficult problem to diagnose that I have EVER experienced. I seem to be unable to call:
exec('call git pull', $output);
The process hangs and tends to take IIS with it.
exec('call git status', $output); //works fine
Here's what I've done:
- Generated RSA key added to github (passcode is blank)
- Everyone has permission on
mysite/.git/
, and Program Files/git/bin
and cmd.exe
- Tried the ssl cert fix mentioned in other posts with 'slash' issue
- Tried using https:// instead of SSH
- Tried piping to stderr
2>NUL
and 2>&1
Clearly, there's a permissions issue where exec
calls cmd.exe
which in turn calls git.exe
, which in turn calls sh.exe
to connect to github, which in turn makes use of git-pull
and possibly git-send-pack
and GOD KNOWS what else.
I'm guessing 'sh.exe' determines the current user is IUSR and cannot find the RSA key to authenticate with.
If I could figure out how to ssh-keygen
the IUSR account, I would have tried that.
If I could figure out how to exec
git bash instead of git (via cmd.exe
) I would have tried that.
Here's the question in it's simplest form:
How do I pull from my github repo via PHP's exec
method?
The problem certainly seems to be with SSH, but I'm totally at the end of everything to try.
Help!
回答1:
I faced the same problem today and used Process Monitor to see what was going on and found that for some reasons sh.exe
looked for the keys in C:\Windows\SysWOW64\config\systemprofile\.ssh
. So I copied everything in C:\Users\Administrator\.ssh
to that folder and it worked perfectly.
回答2:
there are a number of php git libraries/tools.
https://git.wiki.kernel.org/index.php/Interfaces,_frontends,_and_tools#git-php
personally i have been hacking with GLIP (git library in php) http://fimml.at/#glip
i have a source fork on github where i have added an archive function.
basically i dynamically create a git command and use php's passthru method to call it.
perhaps looking at my code might give you some insight. here's the commit
https://github.com/fontvirus/glip/commit/89127f7f9a4dc61697929f36684533406f348ffe
回答3:
I am running Windows Server 2012 and wasn't able to get Iamz's solution to work.
I searched for ".ssh" in my C:\
and noticed that there was another .ssh folder at C:\Program Files (x86)\Git\.ssh
. I copied all the contents from C:\Users\Administrator\.ssh
to this folder, set permissions to allow IUSR access, and everything was kosher.
回答4:
You will have to give permissions directly to cmd.exe. Depending on the version of windows and the way you have your app-pool setup it could be IIS_IUSR, IUSR, and/or NETWORK SERVICE. Add the user with full permissions to cmd.exe.
I, of course, don't recommend doing that since it has direct security implications. That said, I haven't found any other way of making it happen in windows.
回答5:
You need to use proc_open and will thus see the problem which most likely is permission related.
Here's a script I use:
<?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()', '');
}
}
?>
回答6:
I was able to get this to work partly by following a lot of what was on here. I ran a batch script which ran
ssh-agent -s
ssh-add -l
to see what keys I had. Before running these commands I set the HOME=/c/Users/Username
environment variable to my user with the correct ssh keys. (I'm using unix path's because I was running it with Git Bash)
回答7:
I don't quite sure about window's environment
but the main problems is ".php file" that call exec command doesn't have permission as administrator (or root in *NIX os)
in my environment I chown that file to have privilege as root (like sudo things)
another way is create new user group that have permission 777 and assign that file to own by that user's group
hope this help
回答8:
I had this issue earlier today and solved it a different way.
My problem was that the IUSR did not have a home folder to put the ssh keys or a git credentials file into.
I created a .sh file that changed the HOME variable before calling git, put my keys in the proper place as if that was it's home folder, then used sh.exe to run the .sh
#!/bin/bash
export HOME="/c/some/location"
git pull
回答9:
Another variant on Iamz's solution is to use the directory C:\Windows\System32\config\systemprofile\.ssh
I arrived at that by running the following script on my IIS server, which immediately indicated that C:\Windows\System32\config\systemprofile\.ssh
was missing (please set $path_of_git and $path_to_repo as appropriate for your machine):
<?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>';
?>
All that being said, I'm still beset by permission issues, so I've found it useful to just declare that HOME
is somewhere else that IUSR can get to easily before each git command, and execute the whole thing with git sh. For example:
\pathToGit\bin\sh -c "export HOME='/c/somewhereIUSRCanGetTo/';git fetch"
Where C:\somewhereIUSRCanGetTo\.ssh\
contains the private key and allowed_hosts files
回答10:
Move your .ssh folder to userprofile dir. You can see you app profile dir in this global variable $_SERVER['USERPROFILE'].
In my case it's C:\Windows\system32\config\systemprofile.
Then give permissions to read/write to this folder (.ssh) for users: IIS_IUSRS, IUSR