2009-05-30 12 views
11

Viene visualizzato questo errore durante l'esecuzione del mio script Perl. Per favore, dimmi come correggere questo errore in Perl.Come risolvere un errore "print() su filehandle chiuso" in Perl?

print() on closed filehandle MYFILE 

Questo è il codice che sta dando l'errore:

sub return_error 
{ 
    $DATA= "Sorry this page is corrently being updated...<p>"; 
    $DATA.= "<A href=\"javascript:history.go(-1)\"> Back </A>"; 
    open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 
    print MYFILE $DATA; 
    close(MYFILE); 
    exit; 
} 

Spero che ora sono più chiare.

+1

Il titolo del post deve essere modificato. Sembra come se fosse un 'errore in Perl'! –

+1

sarebbe utile se l'avviso di Perl "print() sul filehandle chiuso" messaggio suggerito anche controllando il filehandle potrebbe essere aperto o meno –

risposta

29

Si desidera eseguire un'azione su MYFILE dopo averlo chiuso (o l'interprete stesso a causa di un errore).

In base all'esempio del codice, il problema potrebbe essere che open non apre realmente il file, lo script potrebbe non essere autorizzato a scrivere sul file.

modificare il codice al seguente per vedere se c'è stato un errore:

open(MYFILE, ">", "/home/abc/xrt/sdf/news/top.html") or die "Couldn't open: $!"; 

Aggiornamento

ysth sottolineato che -w non è veramente bravo a controllare se è possibile scrivere sul file , solo 'verifica che uno dei flag rilevanti nella modalità sia impostato'. Inoltre, brian d foy mi ha detto che il condizionale che ho usato non è buono a gestire l'errore. Così ho rimosso il codice fuorviante. Usa invece il codice sopra.

+1

Preferirei i tre argomenti open: open (MYFILE, '>', $ file) ... – Svante

+0

@Svante: grazie, Brad ha appena corretto che :) –

+0

-w non controlla che tu possa scrivere sul file, controlla che uno dei flag rilevanti nella modalità sia impostato. Questo può produrre sia falsi positivi che falsi negativi. Stai molto meglio semplicemente provando ad aprirlo per scrivere e scoprire un errore aperto. – ysth

1

Da qualche parte sei script che farà qualcosa di simile:

open MYFILE, "> myfile.txt"; 
# do stuff with myfile 
close MYFILE; 
print MYFILE "Some more stuff I want to write to myfile"; 

L'ultima riga genera un errore perché MYFILE è stato chiuso.

Aggiornamento

Dopo aver visto il codice, sembra che il file che si sta tentando di scrivere a non possono essere aperti in primo luogo. Come altri hanno già detto provare a fare qualcosa di simile:

open MYFILE, "> myfile.txt" or die "Can't open myfile.txt: $!\n" 

che dovrebbe dare un feedback sul motivo per cui non è possibile aprire il file.

+0

ho scritto anche il mio codice ............... vedere e aiutarmi con la soluzione –

3

questo:

open(MYFILE,">/home/abc/xrt/sdf/news/top.html"); 

In modern Perl, potrebbe essere scritto come:

open(my $file_fh, ">", "/home/abc/xrt/sdf/news/top.html") or die($!); 

questo modo si ottiene una variabile $ ristretto al campo di applicazione, non c'è "business funky", se si avere nomi di file strani (ad es. iniziando con ">") e gestione degli errori (è possibile sostituire die con warn o con codice di gestione degli errori).

Una volta chiuso $ file_fh o semplicemente uscito dall'ambito, non è più possibile stampare su di esso.

12

Sembra che la chiamata open non riesca. È necessario sempre controllare lo stato quando si apre un filehandle.

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(MYFILE, ">$file") or die "Can't write to file '$file' [$!]\n"; 
print MYFILE $DATA; 
close MYFILE; 

Se l'apertura non ha esito positivo, la variabile incorporata $! (a.k.a. $ OS_ERROR) conterrà il messaggio di errore del deploy OS, ad es. "Permesso negato"

E 'anche preferibile (per le versioni non-arcaiche di Perl) per utilizzare il modulo a tre argomenti di open e filehandles lessicali:

my $file = '/home/abc/xrt/sdf/news/top.html'; 
open(my $fh, '>', $file) or die "Can't write to file '$file' [$!]\n"; 
print {$fh} $DATA; 
close $fh; 
+0

So che è in PBP, ma non riesco ad abituarmi all'aspetto di 'stampa {$ fh} $ DATA' per stampare su filehandle. Sembra solo sbagliato. – Telemachus

3

Controllare che il aperta lavorato

if(open(my $FH, ">", "filename") || die("error: $!")) 
{ 
    print $FH "stuff"; 
    close($FH); 
} 
+1

Non è necessario il costrutto if(). Quando è falso, muori già. :) –

6

Una soluzione alternativa a dire or die è quello di utilizzare il autodie pragma:

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 

open my $fh, "<", "nsdfkjwefnbwef"; 

print "should never get here (unless you named files weirdly)\n"; 

Il codice precedente produce il seguente errore (a meno che un file chiamato nsdfkjwefnbwef esiste nella directory corrente):

Can't open 'nsdfkjwefnbwef' for reading: 'No such file or directory' at example.pl line 7 
2

Se si utilizza un MYFILE simbolo globale come filehandle, piuttosto che un locale lessicale ($ myfile), invariabilmente ti imbatterai in problemi se il tuo programma è multithreaded, ad es se è in esecuzione tramite mod_perl. Un processo potrebbe chiudere il filehandle mentre un altro processo sta tentando di scrivere su di esso. L'utilizzo di $ myfile eviterà questo problema poiché ogni istanza avrà la propria copia locale, ma si verificheranno comunque problemi in cui un processo potrebbe sovrascrivere i dati scritti da un altro. Usa flock() per bloccare il file mentre ci scrivi.

3

Ho riscontrato questo problema quando i miei file sono stati impostati su SOLO LETTURA.

Controlla anche questo, prima di arrendersi! :)

Problemi correlati