2012-06-11 83 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。