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"