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.
3 réponses
Si c'est encore utile, deux choses me viennent à l'esprit:
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.
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();
}
# 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
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.