Domanda

Voglio eseguire less e programmi simili dalla riga di comando in PHP.

Ho provato i soliti noti (exec, shell_exec, passanti, ecc), e mentre molti di loro possono scaricare il file sullo schermo, il processo è terminato prima che io possa fare uso di esso. Se avessi voluto cat, lo userei.

Come faccio a eseguire un programma in questo modo?

È stato utile?

Soluzione

Si potrebbe usare proc_open all'ingresso di alimentazione per e tornare uscita da un processo tramite tubi. Tuttavia, non sembra meno consente un'interazione con l'utente tramite tubi in quanto fondamentalmente si degrada a un comando cat. Ecco il mio primo (fallito) approccio:

<?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);

Credo che per alcuni comandi questo approccio potrebbe effettivamente lavoro - e ci sono alcuni esempi nella pagina di manuale PHP per proc_open che potrebbe essere utile a guardare oltre - ma per less, si ottiene tutta la schiena del file e senza possibilità di interazione, forse per i motivi citati dalla risposta di Viper_Sb.

... Ma sembra abbastanza facile da less simulare se questo è tutto ciò che serve. Ad esempio, è possibile leggere l'output del comando in una matrice di righe e alimentarlo in pezzi morso dimensioni:

<?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);
  }
}

Altri suggerimenti

Non credo che questo sia possibile. PHP non è un / ambiente shell VM, i comandi che deve accedere a tutti gli altri programmi di controllo restituito ad esso, e normalmente non v'è alcuna interazione mentre PHP gira.

Un ultima cosa, provate con gli operatori di apice inverso, se questo non funziona, allora io sono abbastanza sicuro che non si può fare questo senza scrivere qualcosa a te stesso che il sonno volontà e consentire l'input dell'utente, ecc ... Per impostazione predefinita, non

`nano file.txt`

L'aggiunta di exec ( 'stty cbreak'); allo script PHP risolve anche il problema.

ho messo il seguente in un file definito dall'impostazione auto_prepend_file in php.ini

Quindi, vorrei fare qualcosa di simile modifica php.ini al seguente:

auto_prepend_file = /path/to/prepend.php

Poi, nel, /path/to/prepend.php, vorrei aggiungere la seguente riga:

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

Io non sono esattamente sicuro della causa. Ho letto le segnalazioni di bug per PHP. Non sono sicuro circa le versioni però. Ho notato che il problema con la seguente configurazione:

$ 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

Tuttavia, quanto segue non ha mostrato il problema:

# 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.

Vale la pena notare che la versione senza il problema stava usando cPanel e l'altro stava usando le CentOS 6 predefinite installare tramite yum.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top