Come posso modificare lo standard output filehandle per una chiamata di sistema in Perl?

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

  •  13-09-2019
  •  | 
  •  

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.

È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top