Perlでファイルとディレクトリ両方をコピー

[上に] [前に] [次に]
Weasel 2000/01/14(金) 18:41:17
CGI(Perl)により、定期的にログファイルをコピーするスクリプトを探していたとき、
J.Nakanishi様にcp.cgiというスクリプトを組んでいただきました。
それを少しカスタマイズして、あるディレクトリの中にあるファイル全てを、
別のディレクトリにコピーするスクリプトを作ろうとしました。

つまり、
/usr/home/aaa
の中にあるファイル全てを
/usr/home/
にコピーするスクリプトです。(ファイル名・ディレクトリ名はそのまま)
下記が、そのスクリプトの変更結果です。

================================================================================

$from_dir = '/usr/home/test'; # コピー元
$to_dir = '/usr/home/'; # コピー先



opendir(DIR, "$from_dir");
@filelist = readdir(DIR);
closedir(DIR);
@filelist = sort(@filelist);
foreach $file (@filelist) {
if ($file eq ".") { next; }
if ($file eq "..") { next; }

system("cp $from_dir/$file $to_dir/$file");
chmod (0666, "$to_dir/$file");
}



================================================================================

しかし、このスクリプトではファイルはコピーできても、ディレクトリが
コピーされないことが判明しました。

opendirというコマンドでは、ディレクトリ内のファイルリストは得られても、
ディレクトリ名は読みこまれないという記述が私のパールリファレンスおよび
とほほさんのサイトで見つけられませんでした。

J.Nakanishiさんにはメールで問い合わせたのですが、少しスクリプトの作成を
急ぐ必要が生じてしまったので、この場に投稿いたしました。

アドバイスお願いします。

ふじ 2000/01/14(金) 20:40:49
結局 system で cp を呼び出すのなら、単に

system "cp -r /usr/home/aaa/* /usr/home";

てするのが早い(速い)のでは。

> opendirというコマンドでは、ディレクトリ内のファイルリストは得られても、
> ディレクトリ名は読みこまれない
そんなことはないです。cp コマンドで(オプションなしで)
ディレクトリを指定してもコピーされない、というだけです。

system("cp $from_dir/$file $to_dir/$file") or print $!;

とでもしてエラーメッセージを見ましょう。

Weasel 2000/01/15(土) 17:55:16
コメント、ありがとうございます。

> 結局 system で cp を呼び出すのなら、単に
> system "cp -r /usr/home/aaa/* /usr/home";
> てするのが早い(速い)のでは。

if関数を利用したいな、という事情がありまして、このような
形にしました。(というより、J.Nakanishiさんが汎用的な
形を考えて、このような形式にしたのだと思います)

/testの中身は、一般に公開したくないファイルが
あり、.htaccessファイルをおいてあります。
そこで、if関数を使って、「.」「..」と同時に
「.htaccess」もコピーしないという形を取りたかったのです。

> そんなことはないです。cp コマンドで(オプションなしで)
> ディレクトリを指定してもコピーされない、というだけです。

そのオプションは、-rでよろしいのでしょうか?
さっそく試して見ます。

> system("cp $from_dir/$file $to_dir/$file") or print $!;
> とでもしてエラーメッセージを見ましょう。

Netscape 4.0(Mac版)で試したところ、
「ドキュメントにデータが含まれていません」という
エラーメッセージが表示されました。
ファイルもコピーされていない様子です。

Weasel 2000/01/15(土) 18:03:00
> そのオプションは、-rでよろしいのでしょうか?
> さっそく試して見ます。

さっそく試したところ、CGIは動いたようで、FTPで
中をみたら、一応コピーされたようなのですが、、、

Fetchでそのディレクトリをダウンロードしようとしたら
「not a regular file」とのこと。
もちろん、ブラウザーで確認しても、ディレクトリ内の
ファイルはまったく表示されませんでした。
これはパーミッションの問題なのでしょうか?

Weasel 2000/01/15(土) 18:49:34
[[解決]]
解決しました。

chmod (0666, "$to_dir/$file");

chmod (0777, "$to_dir/$file");
にしたら、問題なく動くようになりました。
最終的なスクリプトは下記の通りです。

============================================

#!/usr/bin/perl


$from_dir = '../home/test';
$to_dir = '../home';


opendir(DIR, "$from_dir");
@filelist = readdir(DIR);
closedir(DIR);
@filelist = sort(@filelist);
foreach $file (@filelist) {
if ($file eq ".") { next; }
if ($file eq "..") { next; }
if ($file eq ".htaccess") { next; }


system("cp -r $from_dir/$file $to_dir/$file");
chmod (0777, "$to_dir/$file");
}

print <<"RESULT";
Content-type: text/html

<html><head>
<title>コピー完了</title>
</head>

<body bgcolor="#ffffff">
コピー完了
</body>
</html>

RESULT

============================================

その昔、Perlは難しいと愚痴ったことがありましたが、
やってみると楽しいですね。
やみつきになりそう。

こんな私を助けていただいた皆さん、とくにJ.Nakanishiさんと
ふじさんには心から感謝します。

[上に] [前に] [次に]