proc_open() vs passthru() (Problème d'affichage)

Petit nouveau ! | 4 Messages

06 avr. 2012, 11:09

Bonjour ;

Je rencontre actuellement un problem avec PHP (CLI)

J'exécute la commande suivante dpkg-reconfigure mysql-server-5.1 comme suite:

		$timeout = 15;
		$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 write to
		);

		$process = proc_open('dpkg-reconfigure mysql-server-5.1', $descriptorspec, $pipes);

		$streams = array(
			'PSTDIN' => $pipes[0],
			'PSTDOUT' => $pipes[1],
			'PSTDERR' => $pipes[2],
			'STDIN' => STDIN
		);

		if (is_resource($process)) {
			while (!feof($pipes[1])) {
				$read = $streams;
				$n = stream_select($read, $write = null, $e = null, $timeout);

				if ($n > 0) {
					foreach ($read as $r) {
						$key = array_search($r, $streams);

						if ($key == 'STDIN') {
							fwrite($streams['PSTDIN'], fflush($streams[$key]));
						} elseif ($key == 'PSTDOUT' || $key == 'PSTDERR') {
							echo fread($streams[$key], 1);
						}
					}
				}
			}
		} else {
			fwrite(STDOUT, "System was unable to execute external command" . PHP_EOL);
		}
J'obtiens l'écran suivant:

Image

Comme vous pouvez le constater dans l'image jointe, la fenêtre de dialogue n'occupe pas tout l'espace disponible.

Or, si j'éxecute exactement la même commande via la function passthru()
passthru('dpkg-reconfigure mysql-server-5.1 2>&1', $retVal);
J'obtiens l'écran suivant:

Image

Ma question est simple:

Comment obtenir le résultat de la deuxième image en exécutant la commande via proc_open ?

J'aimerais bien savoir ce qui provoque une telle différence.

Vous remerciant par avance.

ViPHP
ViPHP | 2287 Messages

07 avr. 2012, 10:01

Hello,

Va voir par ici : http://en.wikipedia.org/wiki/Termcap (et n'hésite pas à suivre les liens et te cultiver sur les terminaux)
if(!@work()){ Nespresso(); } else { what(); }
______________________________

Petit nouveau ! | 4 Messages

06 juil. 2012, 12:36

Hello,

Va voir par ici : http://en.wikipedia.org/wiki/Termcap (et n'hésite pas à suivre les liens et te cultiver sur les terminaux)
Merci pour votre réponse.

Pour ceux que cela intéresse (exécuter whiptail ou dialog via PHP), Voici un sample (CLI script) :
#!/usr/bin/env php
<?php

$pipes = array(null, null, null);
$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
 *
 * @param bool $wantinputfd Whether or not input fd (pipe) is required
 * @return int Command exit code
 */
function processStop($wantinputfd = false)
{
    global $output, $pipes, $process, $ret;

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

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

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

    if ($errors) {
        fwrite(STDERR, "whiptail 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("whiptail --backtitle 'whiptail 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("whiptail --backtitle 'whiptail 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(true);
echo "Exit code is $ret\n";

// Test for input dialog box
processStart("whiptail --backtitle 'whiptail 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("whiptail --backtitle 'whiptail test' --title 'Little test' --output-fd 3 --inexistent -- 'my input box' 0 70");
processStop();

exit(0);
Note: whiptail est un frontend fournit par Debian. Vous pouvez aussi utiliser dialog de la même manière). Notez qu'il s'agit juste d"un sample. Une approche objet évite l'usage des variables globales...