Redirection de STDERR dans PHP exec

J’écris un script PHP qui doit faire des appels aux utilitaires de ligne de commande externes, pour lesquels j’utilise exec (). Tout fonctionnait bien localement, mais lorsque je l’ai transféré sur un serveur en direct, cela ne fonctionne plus.

Après quelques débogages, je pense que le problème est dû à la redirection de STDERR – si j’essaie de faire quelque chose avec la redirection (redirect vers STDIN, redirect vers un fichier), la commande échoue complètement.

J’ai écrit un script de chauve-souris simple pour simplifier le test:

@echo off echo STDOUT test echo STDERR test 1>&2 

Et puis en PHP:

 &1"; exec($cmd, $output, $status); var_dump($output); var_dump($status); ?> 

Sur le serveur local, le résultat est $ status = 0, $ output = array (“test STDOUT”, “test STDERR”), mais sur le serveur live, le résultat est $ status = 1 et la sortie est vide. tableau!

Si je supprime la partie 1> & 2, j’obtiens le même résultat pour les deux parties (juste la partie STDOUT), donc la commande elle-même fonctionne clairement comme prévu.

Y a-t-il quelque chose de simple qui me manque ici? Si cela vous aide, le serveur exécute Windows Server 2008 R2.

$o = null; $r = null; exec("php test.php 2>&1", $o, $r ); C’est assez simple

Mise à jour et réponse pour le bénéfice de quiconque vient ici avec un problème similaire.

Après avoir passé beaucoup de temps là-dessus, j’ai abandonné exec() et proc_open() plutôt essayé proc_open() .

Le faire de cette façon fonctionne maintenant localement et sur le serveur:

  array("pipe", "r"), // STDIN 1 => array("pipe", "w"), // STDOUT 2 => array("pipe", "w"), // STDERR ); $cwd = getcwd(); $env = null; $proc = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env); if (is_resource($proc)) { // Output test: echo "STDOUT:
"; echo "
".stream_get_contents($pipes[1])."

"; echo "STDERR:
"; echo "

".stream_get_contents($pipes[2])."

"; $return_value = proc_close($proc); echo "Exited with status: {$return_value}"; } ?>

Pour une raison quelconque, l’absence de la partie getcwd() entraîne l’échec de la commande sur le serveur, sauf si je spécifie le chemin complet, alors que localement, cela ne pose aucun problème.

Avec cette méthode, je peux append 2>&1 pour redirect toutes les sorties vers STDIN. Pour sortir dans un fichier, le manuel montre que le tableau $ descriptorspec peut être modifié, par exemple: 2 => array("file", "stderr.log", "a") (je ne l’ai pas encore testé)

Une différence ici est que si je veux récupérer la sortie en PHP, plutôt que d’obtenir toutes les lignes d’un tableau, je dois lire les stream en utilisant stream_get_contents() .

Je ne comprends toujours pas pourquoi il y avait un problème avec l’utilisation de exec() , mais cette méthode semble fonctionner à la fois localement et sur le serveur – Si quelqu’un sait pourquoi cela pourrait être, faites-le moi savoir!