Come posso modificare lo standard output filehandle per una chiamata di sistema in Perl?
Domanda
Sto cercando di modificare il stdout della funzione di sistema usando il tasto select.Ma non sembra funzionare.L'uscita del sistema è sempre visualizzato sulla console piuttosto che ottenere reindirizzato al file.
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" ;
Anche se non posso fare system "dir /a > out.txt"
, Vorrei sapere perché il codice di cui sopra non funziona.
Soluzione
La funzione select
cambia il filehandle di default per l'output. Non cambia STDOUT, che punta a tutto ciò che punti a prescindere se è il filehandle di default per l'output. Se si desidera cambiare STDOUT, si deve fare qualcosa di simile ylebre o la risposta di Jon.
Quando si avvia un processo figlio, ottiene lo stesso standard output come il genitore. Non importa ciò che il filehandle di default del genitore è però.
Altri suggerimenti
Il problema con il vostro codice è che il comando system
non catturare l'output per voi. È possibile utilizzare 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 $!;
Ci sono altre opzioni per eseguire un'applicazione esterna e ottenere leggere il suo output, come i moduli IPC::Open2
e IPC::Open3
. Sono compresi nel perl per impostazione predefinita.
Una nota a margine: non utilizzare gocce di handle di file: sono globali, e globali sono il male. Utilizzare le variabili lessicali invece (FH
vs. $fh
). Inoltre, si dovrebbe usare il open
tre argomenti invece di due parametri, dal momento che il primo è più sicuro rispetto al secondo.
Forse questo aiuta
Non sono sicuro di 'selezionare' è quello che state cercando in questo caso. Per reindirizzare STDOUT a un file, è possibile effettuare le seguenti operazioni:
use strict;
use warnings;
use IO::Handle;
open FH, "> out.txt";
STDOUT->fdopen( \*FH, 'w' ) or die $!;
print "Hello world!\n";
system "dir /a";
Spero che questo aiuti!
I riassegnare i descrittori di file al sistema (non Perl) Livello:
sub reopen($$$) {
open $_[0], $_[1]. '&='. fileno($_[2]) or die "failed to reopen: $!";
}
reopen *STDOUT, '>', $new_stdout_handle;
Ora tutto ciò che si forchetta penserete $ new_stdout_handle è standard output.
Ho incollato un esempio completo di Gist: http://gist.github.com/129407