2012-08-29 4 views
2

Je voudrais que la sortie d'un processus créé avec proc_open soit redirigée vers un autre créé avec proc_open (en php). Par exemple. En bash je peux faire:Connectez les tuyaux des processus en php

[[email protected] ~]$ cat foo 
2 
3 
1 
[[email protected] ~]$ cat foo | sort 
1 
2 
3 
[[email protected] ~]$ 

Je voudrais simuler cela en php avec la fonction proc_open (au lieu de shell_exec) afin d'avoir le contrôle de retour des codes, des tuyaux, etc. Je veux quelque chose comme ceci:

$catPipes=array(); 
$sortPipes=array(); 
$cwd = '/tmp'; 
$env = array(); 
$catProcess = proc_open("cat foo", array(
     0 => array("pipe", "r"), 
     1 => array("pipe", "w") 
    ), $catPipes, $cwd, $env); 

$sortProcess = proc_open("sort", array(
    0 => array("pipe", "r", $catPipes[1]), 
    1 => array("pipe", "w"), 
    ), $sortPipes, $cwd, $env); 

echo stream_get_contents($sortPipes[1]); 
fclose($sortPipes[1]); 
//proc_close(this) ... proc_close(that) ... etc 

Est-ce que quelqu'un pourrait savoir comment je peux simuler le "|" de bash en php, c'est-à-dire relier le second descripteur du cat-process au premier descripteur du processus de tri? Toute aide serait appréciée! Mais s'il vous plaît ne me redirigez pas vers shell_exec, car je veux être en mesure de vérifier les codes de sortie et les erreurs de journalisation :).

EDIT:

Mes besoins au travail-business solution est BTW:

while(!feof($searchPipes[1])) fwrite($lookupPipes[0], stream_get_line($searchPipes[1], 40000)); 

Ce qui est essentiellement ce que le système d'exploitation ferait, mais je ne veux pas mon propre pipe gestion , comme j'ai un noyau/posix pour cela, et soyons honnêtes, ce n'est pas 1976 :)

Répondre

2

Oui, vous pouvez - mais je pense que vous devez définir ce chemin. Que vous pouvez utiliser le STDIN de "sort" comme tube STDOUT pour "cat". Jetez un coup d'œil à ce qui suit, qui travaille pour moi:

<?php 

$txt = "a\nc\ne\nb\nd\n"; 
$fh = fopen('data://text/plain;base64,' . base64_encode($txt), 'r'); 

$sort_pipes = array(); 
$sort_proc = proc_open(
    'sort', 
    array(
     array('pipe', 'r'), 
     STDOUT 
    ), 
    $sort_pipes 
); 

$cat_pipes = array(); 
$cat_proc = proc_open(
    'cat', 
    array(
     $fh, 
     $sort_pipes[0] 
    ), 
    $cat_pipes 
); 

Dans les deux premières lignes i défini un flux de données à partir d'une chaîne de texte que je ne dois pas compter sur un fichier quelque part dans le système de fichiers. Notez que j'ai une liste de caractères non triés stockés dans le flux de données (a, c, e, b, d). L'exécution du script ci-dessus devrait renvoyer une liste triée à STDOUT.

Notez que vous pouvez également spécifier des ressources en tant que descripteurs. Dans ce cas, vous devez omettre la notation de tableau, donc:

STDOUT 

au lieu de

array(STDOUT) 

etc.

.: Btw vous pouvez même écrire directement dans un fichier spécifié par un nom de fichier . Vous trouverez de plus amples informations sur la spécification du descripteur dans la saisie manuelle pour proc_open à http://en.php.net/manual/de/function.proc-open.php

EDIT

L'autre façon fonctionne aussi, bien sûr: vous pouvez aussi écrire « chat » à un tuyau STDOUT array('pipe', 'w') et utilisez $cat_pipes[1] comme STDIN pour "trier". :)

+0

Je suis désolé de ne pas avoir remarqué votre réponse :) Je l'ai déjà corrigé avec un hack, mais aujourd'hui j'ai vérifié votre code, et cela fonctionne et est opérationnel en ce moment même! Merci beaucoup! :) – Herbert