2016-06-07 2 views
3

У меня есть скрипт python, который очень затрудняет работу с Ubuntu 12.02 с помощью Python 2.7.3.shutil samefile error on Linux

PS: он работает без проблем в Windows.

>>> import os 
>>> import shutil 

>>> shutil.copy("/mnt/my_network_dive/somewhere/sample.xml", "/mnt/my_network_drive/COMPLETED/") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.7/shutil.py", line 117, in copy 
     copyfile(src, dst) 
    File "/usr/lib/python2.7/shutil.py", line 69, in copyfile 
     raise Error("`%s` and `%s` are the same file" % (src, dst)) 
shutil.Error: `/mnt/my_network_dive/somewhere/sample.xml` and `/mnt/my_network_drive/COMPLETED/sample.xml` are the same file 

Проверка некоторых свойств файлов:

>>> os.path.exists("/mnt/my_network_drive/somewhere/sample.xml") 
True 
>>> os.path.exists("/mnt/my_network_drive/COMPLETED/sample.xml") 
True 
>>> os.stat("/mnt/my_network_drive/somewhere/sample.xml") 
posix.stat_result(st_mode=33272, st_ino=4913809333, st_dev=25L, st_nlink=1, st_uid=1000, st_gid=0, st_size=5447, st_atime=1465311674, st_mtime=1465311674, st_ctime=1465311685) 
>>> os.stat("/mnt/my_network_drive/COMPLETED/sample.xml") 
posix.stat_result(st_mode=33272, st_ino=4913809333, st_dev=25L, st_nlink=1, st_uid=1000, st_gid=0, st_size=10, st_atime=1465317482, st_mtime=1465317482, st_ctime=1465317483) 
>>> os.path.islink("/mnt/my_network_drive/somewhere/sample.xml") 
False 
>>> os.path.islink("/mnt/my_network_drive/COMPLETED/sample.xml") 
False 

>>> shutil._samefile("/mnt/my_network_dive/somewhere/sample.xml", "/mnt/my_network_drive/COMPLETED/sample.xml") 
False 

Как вы видите, вызывая shutil._samefile я получаю False но shutil.copy еще поднять samefile error.

Я что-то забыл? Любой другой способ перемещения или копирования файлов с помощью Python?

+0

Нет необходимости копировать их. Это две разные записи в каталоге, указывающие на один и тот же файл. Будучи одним и тем же файлом, нет никакого способа, которым их содержимое может отличаться. –

+0

(Почему 'shutil._samefile' возвращает False - это другой вопрос, и, возможно, что-то, чтобы подать ошибку, но поскольку' st_dev' и 'st_ino' идентичны, нет сомнений в том, что это действительно тот же контент, на который указывают оба записи в каталоге). –

+1

@vmenezes Первый аргумент копии в первом поле содержит погружение instread на диске, это только опечатка? –

ответ

2

Похоже, что оба файла являются жесткими ссылками на один и тот же файл. Вы можете сказать, потому что у них одинаковый индекс inode

st_ino=4913809333 

Пользователи Windows обычно не создают жесткие ссылки. Они чаще встречаются в среде Linux, поэтому до сих пор вы не сталкивались с этой проблемой.

Странно, что samefile возвращает False. Какую ОС вы используете? shutil._samefile - это всего лишь обертка вокруг os.path.samefile (о системах, где эта функция существует). Какие результаты вы получили от os.path.samefile? На Posix системы, он просто проверяет, что устройство и инода матч (который они делают в вашем случае) и она должна возвращать True

posixpath.py

def samefile(f1, f2): 
    s1 = os.stat(f1) 
    s2 = os.stat(f2) 
    return samestat(s1, s2) 

def samestat(s1, s2): 
    return s1.st_ino == s2.st_ino and s1.st_dev == s2.st_dev 
+0

Скорее всего, один или оба родительских каталога являются символическими ссылками на один и тот же каталог. – tdelaney

+0

@tdelaney Но 'samefile' должен в этом случае возвращать' True', правильно? –

+0

Да, я так озадачен этим, как ты. Как и при жесткой ссылке, dev и inode должны быть одинаковыми. – tdelaney

0

В питона 3 в shutil. копия есть дополнительный аргумент follow_symlinks = True Посмотрите на это https://docs.python.org/3/library/shutil.html

Если follow_symlinks является ложным, и ЦСИ является символической ссылкой, ДСТ будет кр как символическая ссылка. Если follow_symlinks истинно и src является символической ссылкой, dst будет копией файла src.

+0

Не отвечает на вопрос П. о Python 2.7.3. – martineau

+0

@martineau Но, возможно, проверка того, как это работает на Python 3, может помочь определить, является ли это проблемой. Если да, возможно, он мог бы взглянуть на источник новой версии и скопировать этот код. –

+0

Как вы знаете, что это не проблема с использованием Python 3? – martineau