2

2 つのディレクトリを同期する小さなスクリプトを作成しました。このスクリプトを使用すると、特定のファイル タイプを同期でき、チェックサムまたは日付によるファイル比較が可能です。比較後、コピーする必要があるファイルのリストが、 shutil.copy2()モジュールを使用するファイル コピー プロシージャに渡されます。さまざまなテストの実行で、shutil.copy2 の奇妙な動作が見つかりました。回避策はありません。

最初: ソースが ext3 ボリュームで、ターゲットが fat32 (メモリ スティック) の場合、shutil はエラーを発生させます。shutil.copy2 がメタデータもコピーしようとするためだと思いますが、これは fat32 ではサポートされていません。しかし、try: except: ステートメントでこのエラーをキャッチする方法がわかりません。

2 つ目: 2 つ目の問題はさらに難しい問題です。ソースとターゲットの両方が ext3 ボリュームです。ソースには、完全な Linux ディレクトリ ツリーのバックアップがいくつかあります。ユーティリティがこれらのディレクトリ ツリーを同期しようとすると、システム パーティションのスペースがなくなるまでスクリプトが無限ループで実行されます。この動作を修正し、stat モジュールを使用して、コピー プロセスを開始する前にソース ファイルが通常のファイルであるかどうかを確認しようとしましたが、役に立ちません。奇妙な動作をする問題のファイルは /proc/661/fd/3 です。他にもいくつかあるかもしれませんが、このファイルをコピーしようとするとメモリが消費されてシステムがフリーズするため、テストできません。

私は数日間、これら 2 つの問題の解決策を見つけようとしましたが、彼女の周りの熟練したプログラマーが私をサポートしてくれることを願っています。

助けてくれてありがとう。

ここに私のファイルコピー手順のコード:

def _filecopy(file_list, from_dir, to_dir, overwrt):
print "Files and directories will be processed: "
for file_tupel in file_list:
    source_file_name = from_dir + file_tupel[1] + file_tupel[0]
    try:
        filemode = os.stat(source_file_name).st_mode
    except:
        filemode = 33205 
    if S_ISREG(filemode):
        target_dir_name = to_dir + file_tupel[1]
        if not os.path.isdir(target_dir_name):
            print "Create directory " + target_dir_name
            _mkdir(target_dir_name)
        target_file_name = target_dir_name + file_tupel[0]
        if os.path.isfile(target_file_name) and overwrt == "mark":
            name_appendix = "_marked_by_sync_as_different_on_" + time.strftime("%a_%d_%b_%Y_%H-%M-%S", time.localtime())
            if target_file_name.find(".") == -1:
                new_target_file_name = target_file_name + name_appendix
                new_source_file_name = source_file_name + name_appendix
            else:
                new_target_file_prefix = target_file_name.rpartition(".")[0]
                new_target_file_extension = target_file_name.rpartition(".")[2]
                new_target_file_name = new_target_file_prefix + name_appendix + "." + new_target_file_extension
                new_source_file_prefix = source_file_name.rpartition(".")[0]
                new_source_file_name = new_source_file_prefix + name_appendix + "." + new_target_file_extension
            print "Rename file " + target_file_name + " in " + new_target_file_name
            os.rename(target_file_name, new_target_file_name)
            print "Copy file " + new_target_file_name + " to " + new_source_file_name
            try:
                shutil.copy2(new_target_file_name, new_source_file_name)
            except:
                print "Could not copy " + new_target_file_name + " to " + new_source_file_name
        print "Copy file " + source_file_name + " to " + target_file_name
        try:
            shutil.copy2(source_file_name, target_file_name)
        except:
            print "Could not copy " + source_file_name + " to " + target_file_name
    else:
        print source_file_name + " seems to be no regular file and will not be copied."

Answer No. 1 のヒントに従うと、 shutil,copy2 ステートメントは次のように変わります。

    shutil.copyfile(source_file_name, target_file_name)
    try:
        #try to set permission bits
        shutil.copymode(new_target_file_name, new_source_file_name)
    except:
        print "Permission bits could not be copied"
    try:
        #try to copy metadata
        shutil.copystat(new_target_file_name, new_source_file_name)
    except:
        print "Metadata could not be copied"  
4

1 に答える 1

0

shutil.copy2()単に。shutil.copy()が続きshutil.copystat()ます。最初の問題を解決するには、のソースshutil.copy2()copystat()をコピーして、パーツをtry-exceptブロックで囲むことをお勧めします。エラートレースバックからキャッチする例外を把握できるはずです。

/procおそらく、ファイルシステムをまったくコピーしたくないでしょう。スクリプトを呼び出すときは常にこれを除外します。

于 2011-12-05T20:07:30.377 に答える