我正在使用ajax向php页面发布(忽略发布的数据,这并不重要)
当我使用命令php addHit.php在linux服务器上运行php页面时,它会正确地回显远程服务器的主机名。然而,在ajax中不会发生这种情况,我得到的只是一个成功函数所在的空白警报。你可以在这里看到它的作用:http://ec2-54-244-169-118.us-west-2.compute.amazonaws.com/bootstrap/jumbotron-narrow/index.php
<script>
$(function() {
$("form[name=addHit]").submit(function() {
alert("I am an alert box!");
var link = $("input[name=link]").val();
var comments = $("input[name=comments]").val();
var datastring = "link="+link+"&comments="+comments;
alert(datastring);
$.ajax({
type: "POST",
url: "/bootstrap/jumbotron-narrow/addHit.php",
data: datastring,
success: function(data, status, xhr) {
alert(data);
},
error: function(httpRequest, textStatus, errorThrown) {
alert("status=" + textStatus + ",error=" + errorThrown);
}
});
alert("here");
return false;
});
});
</script>
我的addHit.php页面
$commands = "ssh -i adoekey.pem ubuntu@ip-10-250-69-130.us-west-2.compute.internal hostname -f ";
echo exec($commands);
@Archetype2是如何解决这个问题的(来自他的帖子):
我必须创建文件夹/var/www/.ssh,并将/root/.ssh文件夹中的项目复制到这个新文件夹中,并将新目录及其内容的所有权更改为www数据。然后我将pem文件的权限更改为400。
从命令获取stderr输出
不使用exec
运行命令,而是使用以下命令(来自"Exec()之后的PHP StdErr"):
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w"), // stderr
);
$command = "ssh -i adoekey.pem ubuntu@ip-10-250-69-130.us-west-2.compute.internal hostname -f ";
$pipes = '';
$process = proc_open($command, $descriptorspec, $pipes, dirname(__FILE__), null);
$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
echo "stdout : 'n";
var_dump($stdout);
echo "stderr :'n";
var_dump($stderr);
$returnCode = proc_close($process);
echo "Return code: " . $returnCode;
当您运行php addHit.php
命令时,您将以您登录的用户身份运行该命令(可能是root用户?)。HTTP服务器很可能有自己的用户,权限受到严重限制。您的服务器配置是什么?你在运行LAMP堆栈吗?
还要尝试使用.pem
文件的绝对文件路径,因为执行php脚本的任何内容都可能将当前工作目录更改为其他内容。
我必须创建文件夹/var/www/.ssh,并将项目从/root/.ssh文件夹复制到这个新文件夹中,并将新目录及其内容的所有权更改为www数据。然后我将pem文件的权限更改为400。
老实说,我认为与其使用proc_open,不如使用phpseclib,一个纯PHP SSH实现。例如
<?php
include('Net/SSH2.php');
include('Crypt/RSA.php');
$ssh = new Net_SSH2('ip-10-250-69-130.us-west-2.compute.internal');
$key = new Crypt_RSA();
$key->loadKey(file_get_contents('adoekey.pem'));
if (!$ssh->login('ubuntu', $key)) {
exit('Login Failed');
}
//stderr will be included in output unless specifically disabled
//$ssh->enableQuietMode();
echo $ssh->exec('hostname -f');
//be quiet mode enabled or not you can still get stderr with $ssh->getStdError()
?>