Python 3 follow_symlinks
В Python 3 большинство методов копирования shutil
изучили аргумент follow_symlinks
, который сохраняет символические ссылки, если выбран.
например. для shutil.copy
:
shutil.copy(src, dest, follow_symlinks=False)
и в документах написано :
shutil.copy(src, dst, *, follow_symlinks=True)
Копирует файл src в файл или каталог dst. src и dst должны быть строками. Если dst указывает каталог, файл будет скопирован в dst с использованием базового имени файла из src. Возвращает путь к вновь созданному файлу.
Если follow_symlinks
равно false, а src является символической ссылкой, dst будет создан как символическая ссылка. Если follow_symlinks` имеет значение true и src является символической ссылкой, dst будет копией файла, на который ссылается src.
Однако есть одна проблема: если вы попытаетесь перезаписать существующий файл или символическую ссылку, произойдет сбой с:
FileExistsError: [Errno 17] File exists: 'b' -> 'c'
в отличие от follow_symlinks=True
, который успешно перезаписывается.
То же самое происходит и для os.symlink
, поэтому я вместо этого использовал:
#!/usr/bin/env python3
import shutil
import os
def copy(src, dst):
if os.path.islink(src):
if os.path.lexists(dst):
os.unlink(dst)
linkto = os.readlink(src)
os.symlink(linkto, dst)
else:
shutil.copy(src, dst)
if __name__ == '__main__':
os.symlink('c', 'b')
os.symlink('b', 'a')
copy('a', 'b')
with open('c', 'w') as f:
f.write('a')
with open('d', 'w'):
pass
copy('c', 'd')
copy('a', 'c')
Протестировано в Ubuntu 18.10, Python 3.6.7.