OVH Cloud OVH Cloud

Réouvrir STDOUT

5 réponses
Avatar
Olivier BONHOMME
Bonjour,

Je dispose d'un programme PERL qui a un moment ferme STDOUT. Une fois
STDOUT fermé, je souhaiterais le réouvrir pour pouvoir réécrire sur la
sortie standard. Le tout se passe dans un CGI. Quelqu'un a t'il une idée
de la solution ?

Merci d'avance

Cordialement,
Olivier BONHOMME

5 réponses

Avatar
Paul Gaborit
À (at) Fri, 29 Jul 2005 10:50:30 +0200,
Olivier BONHOMME écrivait (wrote):
Je dispose d'un programme PERL qui a un moment ferme STDOUT. Une fois
STDOUT fermé, je souhaiterais le réouvrir pour pouvoir réécrire sur la
sortie standard. Le tout se passe dans un CGI. Quelqu'un a t'il une idée
de la solution ?


Ne pas fermer STDOUT du tout ?

Une possibilité consiste à dupliquer STDOUT vers un autre FileHandle
puis à fermer STDOUT puis à redupliquer le FileHandle vers STDOUT.

Pour en savoir plus :

perldoc -q dup
perldoc perlfaq5

ou (en français) :

<http://perl.enstimac.fr/DocFr/perlfaq5.html#comment%20faire%20un%20dup()%20sur%20un%20descripteur%20en%20perl>

Mais votre demande me semble bizzare...

Si vous voulez empêcher votre script d'écrire sur STDOUT alors qu'il
le fait, en fermant STDOUT, vous récupérez des warnings du style :

print() on closed filehandle STDOUT

Si ce sont des programmes externes qui écrivent alors redirigez leur
sortie standard vers /dev/null. C'est quand même plus simple.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Olivier BONHOMME
Mais votre demande me semble bizzare...

Si vous voulez empêcher votre script d'écrire sur STDOUT alors qu'il
le fait, en fermant STDOUT, vous récupérez des warnings du style :

print() on closed filehandle STDOUT

Si ce sont des programmes externes qui écrivent alors redirigez leur
sortie standard vers /dev/null. C'est quand même plus simple.



Oui j'avoue que c'est un peu usine a gaz. En fait dans mon CGI j'utilise
les méthodes de daemonization indiquée dans perldoc perlipc. Dans cette
doc, ils expliquent que avant le fork qui va lancer le démon, je dois
rediriger STDOUT vers /dev/null. Or le problème est qu'après le
lancement du démon, je dois afficher du HTML et vu que STDOUT pointe
vers null, plus rien ne s'affiche sur ma page.

Pour information, je suis un débutant en perl et je découvre au fur et a
mesure donc peut être que je m'y prends mal.

Merci pour vos réponses

Cordialement,
Olivier BONHOMME

Avatar
Paul Gaborit
À (at) Fri, 29 Jul 2005 14:07:23 +0200,
Olivier BONHOMME écrivait (wrote):
Oui j'avoue que c'est un peu usine a gaz. En fait dans mon CGI j'utilise
les méthodes de daemonization indiquée dans perldoc perlipc. Dans cette
doc, ils expliquent que avant le fork qui va lancer le démon, je dois
rediriger STDOUT vers /dev/null. Or le problème est qu'après le
lancement du démon, je dois afficher du HTML et vu que STDOUT pointe
vers null, plus rien ne s'affiche sur ma page.


Mais un démon ne doit pas communiquer avec le client... en tous cas
pas directement.

Une manière de voir les choses :

1- le CGI lance le démon (si il ne tourne pas déjà) puis répond au
client que le lancement est effectué.

2- le démon tourne tout seul (donc détaché du serveur Web) et écrit ses
éventuels résultats dans un fichier. Lorsqu'il a terminé, il ajoute en
fin de fichier un marqueur spécial.

3- le CGI, lorsqu'il est à nouveau interrogé et si il y a un fichier
résultat, peut en afficher le contenu. Si en plus il détecte le
marqueur spécial de fin, il sait que le démon s'est terminé. Il peut
alors effacer le fichier de résultat pour permettre un nouveau
lancement du démon (en renvenant au point 1).

C'est en gros la philosophie du truc. Bon, il faut tout de même gérer
en plus le fait que plusieurs instances du CGI peuvent être exécutées
simultanément.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Paul Gaborit
À (at) Fri, 29 Jul 2005 14:07:23 +0200,
Olivier BONHOMME écrivait (wrote):
Oui j'avoue que c'est un peu usine a gaz. En fait dans mon CGI j'utilise
les méthodes de daemonization indiquée dans perldoc perlipc. Dans cette
doc, ils expliquent que avant le fork qui va lancer le démon, je dois
rediriger STDOUT vers /dev/null. Or le problème est qu'après le
lancement du démon, je dois afficher du HTML et vu que STDOUT pointe
vers null, plus rien ne s'affiche sur ma page.


Ma réponse précédente était un peu à côté...

Pour le problème que vous évoquez : la réouverture de STDOUT (et de
STDERR et STDIN et l'utilisation de setsid() pour être complet) vers
/dev/null (ou autre chose) se fait juste *après* le fork (elle ne doit
avoir lieu que pour le démon).

Ainsi le père continue à faire son boulot de CGI et le fils se détache
complètement du son père.

Ce qui est expliqué dans perlfaq8 (perldoc -q daemon) ne correspond
qu'à la situation du fils car dans ce cas précis le père est le shell
qui a lancé le script.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
Olivier BONHOMME
À (at) Fri, 29 Jul 2005 14:07:23 +0200,
Olivier BONHOMME écrivait (wrote):

Oui j'avoue que c'est un peu usine a gaz. En fait dans mon CGI j'utilise
les méthodes de daemonization indiquée dans perldoc perlipc. Dans cette
doc, ils expliquent que avant le fork qui va lancer le démon, je dois
rediriger STDOUT vers /dev/null. Or le problème est qu'après le
lancement du démon, je dois afficher du HTML et vu que STDOUT pointe
vers null, plus rien ne s'affiche sur ma page.



Ma réponse précédente était un peu à côté...

Pour le problème que vous évoquez : la réouverture de STDOUT (et de
STDERR et STDIN et l'utilisation de setsid() pour être complet) vers
/dev/null (ou autre chose) se fait juste *après* le fork (elle ne doit
avoir lieu que pour le démon).

Ainsi le père continue à faire son boulot de CGI et le fils se détache
complètement du son père.

Ce qui est expliqué dans perlfaq8 (perldoc -q daemon) ne correspond
qu'à la situation du fils car dans ce cas précis le père est le shell
qui a lancé le script.



Merci pour toutes vos pistes. La pour l'instant j'ai bidouillé un truc
avec un rechargement de page en javascript qui fonctionne bien mais
techniquement parlant ca ne me plait pas. Je testerais votre solution
dès mon retour de vacances :)

Merci encore

Cordialement,
Olivier BONHOMME