web-dev-qa-db-ja.com

Perlで「閉じたファイルハンドルのprint()」エラーを解決するにはどうすればよいですか?

Perlスクリプトの実行中にこのエラーが発生します。 Perlでこのエラーを修正する方法を教えてください。

print() on closed filehandle MYFILE

これはエラーを引き起こしているコードです:

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;
}

私は今私がより明確になることを願っています。

13
shweta rungta

MYFILE(またはエラーのためにインタープリター自体)を閉じた後、何らかのアクションを実行したいとします。

コードサンプルによると、問題はopenが実際にファイルを開かないことである可能性があり、スクリプトにはファイルへの書き込み権限がない可能性があります。

コードを次のように変更して、エラーが発生したかどうかを確認します。

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

更新

ysth-wは、ファイルに書き込めるかどうかを確認するのはあまり得意ではなく、「モード内の関連するフラグの1つが設定されていることを確認する」だけです。さらに、 brian d foy は、私が使用した条件はエラーの処理が苦手だと教えてくれました。そこで、誤解を招くコードを削除しました。代わりに上記のコードを使用してください。

30
viam0Zah

open呼び出しが失敗しているようです。 常にファイルハンドルを開くときにステータスを確認する必要があります。

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;

オープンに失敗した場合、組み込み変数$! (別名$ OS_ERROR)には、OS依存のエラーメッセージが含まれます。 "アクセス拒否"

また、(非古風なバージョンのPerlの場合)3つの引数形式のopenと字句ファイルハンドルを使用することもお勧めします。

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;
13
Michael Carman

or dieと言う別の解決策は、 autodie プラグマを使用することです。

#!/usr/bin/Perl

use strict;
use warnings;
use autodie;

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

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

上記のコードは、次のエラーを生成します(nsdfkjwefnbwefという名前のファイルが現在のディレクトリに存在しない場合)。

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

この:

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

現代のPerl では、次のように書くことができます。

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

このようにして、スコープに制限された$変数を取得します。奇妙なファイル名(たとえば、「>」で始まる)とエラー処理(dieをwarnまたはエラー処理コードに置き換えることができます)がある場合、「ファンキーなビジネス」はありません。

$ file_fhを閉じるか、単にスコープから外れると、そのファイルに印刷できなくなります。

3
nxadm

オープンが機能したことを確認します

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

ファイルが読み取り専用に設定されているときに、この問題が発生しました。

あきらめる前に、これもチェックしてください! :)

3
Chris Snow

ローカルレキシカル($ myfile)ではなくグローバルシンボルMYFILEをファイルハンドルとして使用する場合、プログラムがマルチスレッドの場合、常に問題が発生します。 mod_Perlを介して実行されている場合。別のプロセスがファイルハンドルに書き込もうとしているときに、あるプロセスがファイルハンドルを閉じている可能性があります。 $ myfileを使用すると、各インスタンスに独自のローカルコピーがあるため、この問題を回避できますが、あるプロセスが別のプロセスが書き込んでいるデータを上書きする可能性があるという問題が発生します。 flock()を使用して、書き込み中にファイルをロックします。

2
Ether

スクリプトのどこかで、次のようなことをします。

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

MYFILEが閉じられているため、最後の行でエラーがスローされます。

更新

コードを見た後、書き込もうとしているファイルを最初から開くことができないようです。他の人がすでに述べたように、次のようなことを試してください。

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

これにより、ファイルを開くことができない理由についてのフィードバックが得られるはずです。

1
Tom Jefferys