2009-09-04 5 views
6

C'è un modo semplice per dire a perl "ora ignorare tutto ciò che viene stampato"?Come posso disattivare temporaneamente STDOUT in un programma Perl?

Devo chiamare una procedura in un modulo Perl esterno, ma la procedura stampa molte informazioni non necessarie (tutto tramite lo standard stampa).

so selezionare può essere utilizzato per reindirizzare in qualche modo, ma non sono troppo saggio dalla lettura perldoc su di esso.

Edit: Ho trovato la risposta più presto, ma io lo renderò un esempio per renderlo più chiaro (ma non molto suppongo)

use TectoMT::Scenario; 
use TectoMT::Document; 

sub tagDocuments { 
    my @documents = @_; 

    my $scenario = TectoMT::Scenario->new({'blocks'=> [ qw(
      SCzechW_to_SCzechM::Sentence_segmentation 
      SCzechW_to_SCzechM::Tokenize 
      SCzechW_to_SCzechM::TagHajic 
      SCzechM_to_SCzechN::Czech_named_ent_SVM_recognizer) ]}); 

    $scenario->apply_on_tmt_documents(@documents); 
    return @documents; 
} 

TectoMT :: scenario e Document TectoMT :: sono quelli esterni I moduli

+0

Prova questa: aperto STDOUT, ">/dev/null"; non è sicuro che cosa succederà ... – Havenard

+0

Come stai chiamando quei moduli? Puoi fornire qualche codice o qualche esempio? –

+0

Peter: tramite una chiamata standard :) Aggiungerò un esempio concreto in ogni caso, ho trovato una risposta prima. Lo posterò come risposta alla mia stessa domanda. –

risposta

12

La mia risposta:

use IO::Null; 

print "does print."; 

my $null = IO::Null; 
my $oldfh = select($null); 

print "does not print."; 

select($oldfh); 

print "does print."; 
+0

Questo è fondamentalmente come lo faccio. –

+3

Questo non funziona per reindirizzare l'output di un sottoprocesso chiamato con 'system'. – Flimm

+0

Non dovresti avere un '-> new' dopo' my $ null = IO :: Null'? Sembra funzionare bene così com'è, ma non capisco come .... – Chad

1
open my $saveout, ">&STDOUT"; 
open STDOUT, '>', "/dev/null"; 

(do your other stuff here) 

open STDOUT, ">&", $saveout; 
+2

problema con questo è voglio il codice per essere multipiattaforma e non tutti i sistemi hanno/dev/null. Fortunatamente, c'è IO :: Null per salvarmi. –

+0

Si potrebbe voler menzionare tale requisito nella domanda –

+0

IO: Null non influisce sui programmi chiamati esterni. ma è possibile utilizzare il metodo sopra per il sistema supportato (perl può rilevare il SO) e IO: Null per non supportato. Puoi coprirlo con la tua funzione che selezionerà automaticamente il metodo corretto. Notare che non solo STDOUT è un problema, lo stesso problema è con STDERR, quindi è necessario reindirizzare entrambi i flussi. – Znik

1

Se si desidera utilizzare solo moduli nella libreria standard, File::Spec ha la funzione devnull(). Restituisce una stringa che rappresenta il dispositivo nullo ("/dev/null" su * nix) che è possibile presumibilmente aprire con open().

6

Mi rendo conto che questo è stato risolto, ma penso che valga la pena conoscere un metodo alternativo per farlo. In particolare, se qualcosa è decisa a stampa per STDOUT ...

# Store anything written to STDOUT in a string. 
my $str; 
open my $fh, '>', \$str; 
{ 
    local *STDOUT = $fh; 
    code_that_prints_to_stdout(); 
} 

Il bit chiave è local *STDOUT. Sostituisce il normale STDOUT con un filehandle di tua scelta, ma solo per l'ambito del blocco contenente lo local.

+2

Questo non funziona per reindirizzare l'output di un sottoprocesso chiamato con 'system'. – Flimm

6

Riferendomi ad alcune risposte qui e su altri thread, mi sono inventato questo;

use strict; 
use warnings; 
use File::Spec; 

sub my_functor { system("some_noisy_command.exe", "--option1", "--option2"); } 
silently(\&my_functor); 

Dove "in silenzio()" prende un funtore e lo gestisce con stdout:

sub silently($) { 
    #Turn off STDOUT 
    open my $saveout, ">&STDOUT"; 
    open STDOUT, '>', File::Spec->devnull(); 

    #Run passed function 
    my $func = $_[0]; 
    $func->(); 

    #Restore STDOUT 
    open STDOUT, ">&", $saveout; 
} 
+0

(Feedback apprezzato - Perl novice) – RJFalconer

+2

Funziona con 'system', a differenza delle altre risposte! – Flimm