Question

Je veux exécuter less et des programmes similaires de la ligne de commande en PHP.

J'ai essayé les suspects habituels (exec, shell_exec, PassThru, etc.), et alors que beaucoup d'entre eux peuvent vider le fichier à l'écran, le processus est terminé avant que je puisse l'utiliser. Si je voulais cat, je l'utilise.

Comment puis-je exécuter un programme de cette façon?

Était-ce utile?

La solution

Vous pouvez utiliser proc_open à l'entrée d'alimentation pour obtenir une sortie et de retour d'un processus par des tuyaux. Cependant, il ne semble pas moins permet une interaction de l'utilisateur par l'intermédiaire des tubes comme il essentiellement à une commande se dégrade de cat. Voici mon premier (échec) approche:

<?php
$dspec = array(
  0 = array('pipe', 'r'), // pipe to child process's stdin
  1 = array('pipe', 'w'), // pipe from child process's stdout
  2 = array('file', 'error_log', 'a'), // stderr dumped to file
);
// run the external command
$proc = proc_open('less name_of_file_here', $dspec, $pipes, null, null);
if (is_resource($proc)) {
  while (($cmd = readline('')) != 'q') {
    // if the external command expects input, it will get it from us here
    fwrite($pipes[0], $cmd);
    fflush($pipes[0]);
    // we can get the response from the external command here
    echo fread($pipes[1], 1024);
  }
fclose($pipes[0]);
fclose($pipes[1]);
echo proc_close($proc);

Je suppose que pour certaines commandes cette approche pourrait en fait le travail - et il y a quelques exemples dans le php manpage pour proc_open qui pourrait être utile de regarder par-dessus - mais pour less, vous obtenez tout le dos de fichier et aucune possibilité d'interaction, peut-être pour les raisons mentionnées par la réponse de Viper_Sb.

... Mais il semble assez facile de less Simuler si c'est tout ce que vous avez besoin. Par exemple, vous pouvez lire la sortie de la commande dans un tableau de lignes et alimenter en morceaux bouchées:

<?php
$pid = popen('cat name_of_file_here', 'r');
$buf = array();
while ($s = fgets($pid, 1024))
  $buf[] = $s;
pclose($pid);
for ($i = 0; $i < count($buf)/25 && readline('more') != 'q'; $i++) {
  for ($j = 0; $j < 25; $j++) {
    echo array_shift($buf);
  }
}

Autres conseils

Je ne crois pas que ce soit possible. PHP est pas une machine virtuelle / environnement shell, les commandes qu'il doit accéder à d'autres programmes tout contrôle de retour à, et normalement il n'y a pas d'interaction en PHP est en cours d'exécution.

Une dernière chose, essayez avec les opérateurs de backtick, si cela ne fonctionne pas alors je suis sûr que vous ne pouvez pas faire cela sans écrire quelque chose que vous sommeil volonté et permettre etc entrée utilisateur ... Par défaut, aucun

`nano file.txt`

Ajout exec ( 'stty cbreak'); au script PHP résout également le problème.

Je mets ce qui suit dans un fichier défini par le paramètre auto_prepend_file dans php.ini

Alors, je ferais quelque chose comme php.ini modifier à ce qui suit:

auto_prepend_file = /path/to/prepend.php

Ensuite, dans, /path/to/prepend.php, j'ajouter la ligne suivante:

if (php_sapi_name() == 'cli') exec('stty cbreak');

Je ne suis pas sûr de la cause. J'ai lu des rapports de bogue pour PHP. Je ne suis pas sûr de versions cependant. J'ai remarqué le problème avec la configuration suivante:

$ php -v
PHP 5.3.3 (cli) (built: Jul 12 2013 20:35:47)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies

Cependant, ce qui suit ne montre pas la question:

# php -v
PHP 5.3.26 (cli) (built: Oct 21 2013 16:50:03)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
    with the ionCube PHP Loader v4.4.1, Copyright (c) 2002-2013, by ionCube Ltd.

Il est à noter que la version sans problème utilisait cPanel et l'autre utilisait les CentOS par défaut 6 installation via yum.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top