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

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : proc_open() vs passthru() (Problème d'affichage)

Re: Exécuter whiptail/dialog via PHP

par nuxwin » 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...

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

par Calimero » 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)

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

par nuxwin » 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.