Comment puis-je réinitialiser stdin/STDOUT/STDERR de Perl?

j'ai un script Perl qui se forge et se démonise lui-même. Il est dirigé par cron, donc afin de ne pas laisser un zombie autour, j'ai éteint STDIN,STDOUT, et STDERR:

open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
if (!fork()) {
  do_some_fork_stuff();
  }

la question que j'ai est: je voudrais restaurer au moins STDOUT après ce point (ce serait bien de restaurer les 2 autres). Mais quels symboles magiques dois-je utiliser pour ré-ouvrir STDOUT comme ce que STDOUT était?

je sais que je pourrais utiliser "/dev/tty" si j'ai été l'exécution d'un ats (mais je suis en cours d'exécution à partir de cron et selon stdout ailleurs). J'ai aussi lu des trucs où vous pouvez mettre STDOUT de côté avec open SAVEOUT,">&STDOUT", mais juste le fait de faire cette copie ne résout pas le problème original de laisser un zombie autour.

je cherche à voir s'il y a de la magie comme open STDOUT,"|-" (ce qui, je le sais, n'est-ce pas) pour ouvrir STDOUT de la façon dont il est censé être ouvert.

16
demandé sur brian d foy 2009-08-28 22:29:39

3 réponses

Si c'est encore utile, deux choses me viennent à l'esprit:

  1. Vous pouvez fermer STDOUT/STDERR/STDIN dans juste le processus enfant (i.e. si (!fourche.))( Cela permettra au parent de les utiliser encore, parce qu'ils seront toujours ouverts là-bas.

  2. je pense que vous pouvez utiliser la plus simple de fermer(STDOUT) au lieu de l'ouvrir vers /dev/null.

Par exemple:

if (!fork()) {
    close(STDIN) or die "Can't close STDIN: $!\n";
    close(STDOUT) or die "Can't close STDOUT: $!\n";
    close(STDERR) or die "Can't close STDERR: $!\n";
    do_some_fork_stuff();
}
5
répondu Michael Krebs 2009-08-29 01:08:53

# copie des descripteurs de fichier

open(CPERR, ">&STDERR");

# rediriger stderr dans d'avertissement fichier

open(STDERR, ">>xyz.log") || die "Error stderr: $!";

# fermer l'redirigé descripteurs

close(STDERR) || die "Can't close STDERR: $!";

# restaurer stdout et stderr

open(STDERR, ">&CPERR") || die "Can't restore stderr: $!";

#j'espère que cela fonctionne pour vous.

#-Hariprasad AJ

15
répondu Hari 2013-01-20 22:46:38

une Fois fermé, il n'y a aucun moyen de la récupérer.

Pourquoi avez-vous encore besoin de STDOUT? Pour écrire des messages sur la console? Utilisez / dev / console pour cela, ou écrivez à syslog avec Sys:: Syslog.

honnêtement cependant, l'autre réponse est correcte. Vous devez enregistrer le vieux stdout (cloné à un nouveau fd) si vous souhaitez rouvrir plus tard. Il résout le problème "zombie", puisque vous pouvez alors rediriger fd 0 (et 1 & 2) vers /dev/null.

4
répondu jmanning2k 2009-08-28 19:43:01