Comment puis-je changer le descripteur de fichier de sortie standard pour un appel système en Perl?

StackOverflow https://stackoverflow.com/questions/990913

  •  13-09-2019
  •  | 
  •  

Question

Je suis en train de changer la stdout de la fonction du système en utilisant select. Mais il ne semble pas fonctionner. La sortie du système est de s'afficher sur la console plutôt que de se rediriger vers le fichier.

use strict;
use warnings;

chdir "C:\\Documents and Settings\\" or die "cannot open the dir\n";
open FH, ">out.txt" or die "cannot open out.txt\n";
select FH or die " cannot change the stdout\n";
system "dir /a" ; 

Bien que je peux faire system "dir /a > out.txt", je veux savoir pourquoi le code ci-dessus ne fonctionne pas.

Était-ce utile?

La solution

La fonction select modifie le descripteur de fichier par défaut pour la sortie. Il ne change pas STDOUT, qui pointe vers ce qu'il souligne, peu importe si elle est le descripteur de fichier par défaut pour la sortie. Si vous voulez changer STDOUT, vous devez faire quelque chose comme ylebre ou la réponse de Jon.

Lorsque vous démarrez un processus enfant, il obtient la même sortie standard en tant que parent. Il ne se soucie pas ce que le descripteur de fichier par défaut du parent est bien.

Autres conseils

Le problème avec votre code est que la commande system ne saisit pas la sortie pour vous. Vous pouvez utiliser qx//:

use strict;
use warnings;

open my $fh, ">", "output.txt" or die $!;
my $oldfh= select $fh;
print qx/ls -a/;
select $oldfh;
close $fh or warn $!;

Il y a d'autres options pour exécuter une application externe et obtenir lu sa sortie, comme les modules de IPC::Open2 et IPC::Open3. Ils sont inclus dans perl par défaut.

Une note de côté: ne pas utiliser pour globs handles de fichiers: ils sont globals, et sont mal globals. Utiliser des variables lexicales à la place (FH par rapport à $fh). , Vous devez également utiliser les trois arguments open au lieu de deux paramètres, puisque le premier est plus sûr que celui-ci.

Peut-être cette aide

Je ne suis pas sûr « select » est ce que vous cherchez dans ce cas. Pour rediriger stdout vers un fichier, vous pouvez faire ce qui suit:

use strict;
use warnings;
use IO::Handle;
open FH, "> out.txt";
STDOUT->fdopen( \*FH, 'w' ) or die $!;
print "Hello world!\n";
system "dir /a";

Hope this helps!

I réaffecter les descripteurs de fichiers au niveau du système (non Perl):

    sub reopen($$$) {
        open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
    }

    reopen *STDOUT,  '>', $new_stdout_handle;

Maintenant, tout ce que vous pensez que la fourchette new_stdout_handle $ est sortie standard.

Je collais un exemple complet essentiel: http://gist.github.com/129407

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top