2012-06-11 84 views
4

我有bash和Perl脚本的集合bash脚本执行从PHP和瞬时输出回到网页

  1. 开发所需部署在Linux操作系统中
  2. (可选)出口代码的目录结构从SVN
  3. 从这个来源

构建一个软件包这是从终端运作良好。现在我的客户请求一个Web界面来处理这个过程。

例如,某些页面上的“创建新包”按钮将逐个调用上述步骤,并将输出作为脚本回显返回给用户,而不是在整个脚本执行时返回。

是否可以通过bash脚本将瞬时输出发送到通过程序执行函数(system,exec,passthru ...或任何其他套件处理流程)调用它的网页或php脚本?

什么是优雅为什么要这样做?

我在做这样的事情时应该采取哪些安全防范措施(如果可能的话)?

编辑 一些搜索后,我已经找到了解决方案的一部分,但仍然没有工作:

$cmd = 'cat ./password.txt|sudo -S ./setup.sh '; 

$descriptorspec = array(
     0 => array("pipe", "r"), // stdin is a pipe that the child will read from 
     1 => array("pipe", "w"), // stdout is a pipe that the child will write to 
     2 => array("pipe", "w") // stderr is a pipe that the child will read from 
); 

flush(); 

$process = proc_open($cmd, $descriptorspec, $pipes, './', array()); 
echo "<pre>"; 
if (is_resource($process)) {  

    while ($s = fgets($pipes[1])) { 
     print "Message:".$s; 
     flush(); 
    } 
    while ($s = fgets($pipes[2])) { 
     print "Error:".$s; 
     flush(); 
    } 
} 
echo "</pre>"; 

输出:(网页),我现在有

Error:WARNING: Improper use of the sudo command could lead to data loss 
Error:or the deletion of important system files. Please double-check your 
Error:typing when using sudo. Type "man sudo" for more information. 
Error: 
Error:To proceed, enter your password, or type Ctrl-C to abort. 
Error: 
Error:Password: 
Error:Sorry, try again. 
Error:Password: 
Error:Sorry, try again. 
Error:Password: 
Error:Sorry, try again. 
Error:sudo: 3 incorrect password attempts** 

首次发行是通过sudo passoword

请帮助!

+0

相关:http://stackoverflow.com/questions/1281140/run-process-with-realtime-output-in-php http://stackoverflow.com/questions/133935/is-there-a-way- php-print-the-data-to-a-web-browser-in-time – jm666

回答

4

我会使用一种主/从设计。奴隶是你的perl/bash脚本,只是做一个工作(打包,编译,导出代码等),并提供一个日志条目。

主人将是你的PHP过程。所以原理如下:主机和从机共享通信通道,并与该通道异步通信。

你可以想像这样一个数据库:

create table tasks (id INT primary key, status INT, argument VARCHAR(100)); 

你的PHP页面应该切换的用户选择,并且过滤输入:

switch ($_GET['action']) { 
    case 'export': 
     $argument = sanitize($_GET['arg']); 
     add_task('export', $argument); 
     break; 
    case '...': 
    // ... 
} 

和add_task功能可能是这样的:

function add_task($action, $arg) 
{ 
    return $db->add('tasks', array($action, NEW_TASK, $arg); 
} 

奴隶可以跑通过cron job,并查询数据库,提供任务的进展。

亲是:

  • 独立的系统,缓解了进化。
  • 如果客户端断开连接,工作永远不会丢失
  • 更容易获得

的缺点是:

  • 在开始稍微复杂一点。
  • 反应性较差,因为运行了奴隶的轮询时间(例如,如果它们运行每5分钟),比命令的直接输出

请注意,你就可以实现XML

  • 输出少-rpc像触发器一样运行从站,而不是使用消息传递系统。

  • +0

    你的答案提供了一些有趣的选项来处理系统。如果你有一些工作代码,或者用这种方式设计的类似脚本/系统,我会很感激。谢谢 – sakhunzai

    +0

    对不起,我只在分布式计算的java项目中使用它们,并且在vhffs中使用perl(vhffs.org,请参阅bot /文件夹)。 – Aif

    +0

    对Alf的建议方法+1。这是满足此类要求的一个非常标准的模式。它有助于解决大多数安全和控制问题,因为它将“请求和监控”域与执行域分开。您可以对这些前端和后端服务使用单独的身份验证和身份验证,并通过接口的数据和流程模型使其交互正式化。 – TerryE

    1

    最简单的方法是使用shell_exec您的目的。它通过shell执行一个命令,并以字符串形式返回完整的输出,因此您可以在网站上显示它。

    如果这不符合您的目的,因为也许您希望在等待命令完成时收到一些响应,请查看php中的其他program execution functions available(提示:在手册页上有几个很好的评论)。

    请记住,通过这种方式唤起命令行脚本时,生成的输出将具有文件所有者,组和Web服务器的权限(p.e. wwwrun或其他)。如果部署的某些部分需要单独的所有者,组和/或文件权限,则必须在脚本中或调用shell_execchmodchownchgrp可以在php中处理此操作)后手动设置它们。

    关于安全性: 许多基于Web的应用程序都将这种功能放到了单独的安装目录中,请您在安装后删除此目录。我甚至记得其中有些人在管理员中大喊大叫,除非它被删除。这是一个简单的方法,可以防止在错误的时间由错误的手调用该脚本。如果您的应用程序在安装后可能需要它,那么您必须将其放入只有授权用户才能访问(p.e. admin区域或类似地址)的区域。

    1

    您可以使用Comet web application model来实时更新结果页面。

    对于sudo问题,作为一个快速和肮脏的解决方案,我会使用一组受限制的命令,Web服务器可以在没有密码的情况下执行。实施例(添加在/etc/sudoers):

    apache ALL=(ALL) NOPASSWD: /sbin/service myproject *

    这将允许阿帕奇到/sbin/service myproject stop/sbin/service myproject start等上运行。

    看看Jenkins,它很好地完成了Web部件,您只需在构建中添加脚本即可。

    Aif所示,更好的解决方案是将逻辑分开。一个守护进程等待任务和一个Web应用程序可视化结果。

    0

    当通过PHP执行系统命令以确保安全时,始终使用escapeshellargescapeshellcmd。也会建议让用户尽可能限制在chroot目录中。

    0

    您似乎已经解决了使用proc_open将stdout和stdin输出到您的网页的问题。现在问题看起来是通过sudo执行脚本。

    从安全角度看,让一个PHP应用程序以root身份运行脚本(通过sudo)会让我畏缩不前。在password.txt中拥有root密码是一个非常巨大的安全漏洞。

    我会做什么(如果可能的话)是做任何必要的更改,以便setup.sh可以由运行Apache的unix用户运行。 (我假设你用Apache运行PHP。)如果setup.sh将由web服务器执行,它应该能够运行它而不诉诸sudo。

    如果您确实需要以其他用户身份执行脚本,您可以检查suPHP,该脚本旨在以非标准用户身份运行PHP脚本。

    0

    使用/ etc/sudoers的NOPASSWD选项向特定用户提供自动sudo权限,然后运行带有前缀sudo -u THE_SUDO_USER的命令,以便以该用户的身份执行该命令。这可以防止给予整个apache用户sudo权限的安全漏洞,但也允许在apache内对脚本执行sudo。