2011-01-17 23 views
2

私は、コマンドラインからのみ行うことができ、 'dialog'コマンドを使ってメッセージボックスを表示しようとするサーバー上で、さまざまな管理タスクを実行するヘルパースクリプトを作成しようとしています、入力、パスワードのプロンプトなどがありますが、このタスクの必要性はPHPでデータを処理する必要があります。PHPのlinux 'dialog'コマンドを使用する

私はダイアログコマンドをこのように動作させるのに問題があり、何が間違っているのか分かりません。

here

残念ながら、それは動作しませんがあります。

PHPとexec/backtick/systemを外部アプリケーションに実行すると、IOが期待どおりに機能しないように見えます。

私はパススルーを使用している得ることができる最も近い()コマンド:

<?php 
    $CMD = "dialog --menu \"Please select\" 10 40 3 backup \"Backup Files\" restore \"Restore Files\""; 
    passthru($CMD); 
?> 

これはPHPはSTDOUT正しく、何も他の表示なしでの結果が、あなたが押すことができ、戻りダイアログを使用するようになる唯一の方法がありますオプションを選択します。

私はbackticks、exec()とsystem()を試しましたが、何も動作していないようです。

私が疑問に思ったのは、$ resultという変数に戻り値を得るためにPHP内からSTDERRを正しく読み込む方法でした。

他のシステム管理者も以前にこれをやっていたことがあります。

私が選択の結果として実行しなければならないコマンドがXML出力のみを生成し、それを効果的にbashで解析できないという理由で、bashを使用しない理由があります。

答えて

0

のためのソリューションのように見える - 多分あなたは、このを見てみる必要があります:http://php.net/manual/de/book.ncurses.php

+0

私の特定のアプリケーションでは、私はこの答えを受け入れられた答えとして取り上げ、調査して、うまくいかなかったproc_open()メソッドを試した後、nfoが言ったようにこれを行うことはできないと結論づけました。私は必要な解決策を得るためにreadline()を使ってダムメニューを実装しなければなりませんでした。ディレクトリブラウザを置くのが好きだったのは残念です。 – JamesB

1

PHP-GTKは、私はあなたがこのようにPHP経由のncursesアプリケーションを実行することはできませんだと思う。この問題 http://gtk.php.net/

+0

PHP-GTKはSSHで動作するため、おそらく私のニーズにあまりにも重量があります。また、デプロイメントを行うためにプリインストールのオーバーヘッドは必要ありません私はPHP-GTKを他のものに使うことに非常に興奮しています。 – JamesB

2

することができますSTDIN、STDOUTとSTDERR、コマンドを実行して、すべてのパイプに対話するproc_open()を使用します。

$pipes = array(NULL, NULL, NULL); 
$proc = proc_open(
    "dialog --gauge ..", 
    array(
     0 => array('pipe', 'r'), 
     1 => array('pipe', 'w'), 
     2 => array('pipe', 'w'), 
    ), 
    $pipes 
); 
print fgets($pipes[2]); 

は、より多くの例のマニュアルを参照してください。

+0

私はpythonを提案します。 *アヒル* – Vangel

+0

凶悪!どのようにあなたを感謝! – mario

4

ちょうど他の誰かがこのために検索された場合には:

function dialog ($args) { 
    $pipes = array (NULL, NULL, NULL); 
    // Allow user to interact with dialog 
    $in = fopen ('php://stdin', 'r'); 
    $out = fopen ('php://stdout', 'w'); 
    // But tell PHP to redirect stderr so we can read it 
    $p = proc_open ('dialog '.$args, array (
     0 => $in, 
     1 => $out, 
     2 => array ('pipe', 'w') 
    ), $pipes); 
    // Wait for and read result 
    $result = stream_get_contents ($pipes[2]); 
    // Close all handles 
    fclose ($pipes[2]); 
    fclose ($out); 
    fclose ($in); 
    proc_close ($p); 
    // Return result 
    return $result; 
} 

それで、それが動作するダイアログ(対話をインストールapt-getの)とproc_xxx(PHP 4.3.0、PHP 5)

が必要です少なくとも私のために。 :)

4

上記のようにproc_open()を使用することはできます...すべてのダイアログボックスは同じように動作しません。私は以下の具体的なサンプルを提供しています:

#!/usr/bin/env php 
<?php 

$pipes = array(); 
$process = null; 
$output = ''; 
$ret = -1; 

/** 
* Start process 
* 
* @param string $cmd Command to execute 
* @param bool $wantinputfd Whether or not input fd (pipe) is required 
* @retun void 
*/ 
function processStart($cmd, $wantinputfd = false) 
{ 
    global $process, $pipes; 

    $process = proc_open(
     $cmd, 
     array(
      0 => ($wantinputfd) ? array('pipe', 'r') : STDIN, // pipe/fd from which child will read 
      1 => STDOUT, 
      2 => array('pipe', 'w'), // pipe to which child will write any errors 
      3 => array('pipe', 'w') // pipe to which child will write any output 
     ), 
     $pipes 
    ); 
} 

/** 
* Stop process 
* 
* @return void 
*/ 
function processStop() 
{ 
    global $output, $pipes, $process, $ret; 

    if (isset($pipes[0]) { 
     fclose($pipes[0]); 
     usleep(2000); 
    } 

    $output = ''; 
    while ($_ = fgets($pipes[3])) { 
     $output .= $_; 
    } 

    $errors = ''; 
    while ($_ = fgets($pipes[2])) { 
     fwrite(STDERR, $_); 
     $errors++; 
    } 

    if ($errors) { 
     fwrite(STDERR, "dialog output the above errors, giving up!\n"); 
     exit(1); 
    } 

    fclose($pipes[2]); 
    fclose($pipes[3]); 

    do { 
     usleep(2000); 
     $status = proc_get_status($process); 
    } while ($status['running']); 

    proc_close($process); 
    $ret = $status['exitcode']; 
} 

// Test for yesno dialog box 
processStart("dialog --backtitle 'dialog test' --title 'Little test' --output-fd 3 --yesno 'yesno dialog box' 0 70"); 
processStop(); 
echo "Exit code is $ret\n"; 

// Test for gauge dialog box 
processStart("dialog --backtitle 'dialog test' --title 'Little test' --output-fd 3 --gauge 'Gauge dialog box' 0 70 0", true); 
sleep(1); 
fwrite($pipes[0], "XXX\n0\nFirst step\nXXX\n20\n"); 
sleep(1); 
fwrite($pipes[0], "XXX\n20\nSecond step\nXXX\n50\n"); 
sleep(1); 
fwrite($pipes[0], "XXX\n50\nThird step\nXXX\n80\n"); 
sleep(1); 
fwrite($pipes[0], "XXX\n80\nFourth step\nXXX\n100\n"); 
sleep(1); 
processStop(); 
echo "Exit code is $ret\n"; 

// Test for input dialog box 
processStart("dialog --backtitle 'dialog test' --title 'Little test' --output-fd 3 --inputbox 'input dialog box' 0 70"); 
processStop(); 
echo "Output is $output\n"; 
echo "Exit code is $ret\n"; 

// Test for errors output 
processStart("dialog --backtitle 'dialog test' --title 'Little test' --output-fd 3 --dummy 'my input box' 0 70"); 
processStop(); 

exit(0); 
+0

同じ方法でDebian whiptailを実行することができます。 – Nuxwin

+1

もちろん、オブジェクトアプローチはより良いサウンドになります。グローバル変数を使用することはお勧めできません(少なくとも、私の側から...)。 – Nuxwin

+0

本当に知りたい人には:https://github.com/i-HMS/sysconf – Nuxwin

関連する問題