Существует ли в Linux программа копирования, которая сохраняет символические ссылки на каталоги и разыменовывает символические ссылки на файлы?

Вопрос или проблема

Мне нужно скопировать дерево каталогов, полное символических ссылок на файлы, на другой раздел, но в каталоге есть 2 или 3 символические ссылки на каталоги за пределами дерева копирования. Мне нужно скопировать символические ссылки, указывающие на файлы, как реальные файлы, но сохранить 2 или 3 символические ссылки на каталоги как символические ссылки.

scp -L перенаправляет все

Я пробовал rsync -avHS, а затем rsync -avHS --keep-dirlinks или rsync -avHS -K, но они сохраняют как ссылки на файлы, так и на каталоги на конечной стороне, так что в итоге ничего не перенаправляется.

Вы могли бы использовать функцию Python shutil.copytree с параметром symlink установленным в False и параметром ignore установленным на функцию, которая проверяет, является ли каталог символической ссылкой (os.path.islink()) и если нет, возвращает пустой список, но если это так, добавляет каталог и его цель (os.readlink) как кортеж в список не следуемых символических ссылок для последующего восстановления и возвращает полный список содержимого (игнорируя всех потомков символической ссылки). Затем вы могли бы использовать список кортежей не следуемых символических ссылок и os.symlink для создания конечных ссылок.

Скорее всего, в вашей Linux-дистрибуции Python уже установлен.

Вот Perl-скрипт из 2005 года, “Наведение порядка в беспорядке символических ссылок”, написанный известным Perl-хакером Рэндаллом Шварцем.

Конечно, он не делает точно то, что вам нужно, но содержит подробные построчные объяснения. Возможно, вы сможете адаптировать его под свои нужды.

.

Ответ или решение

Если вы ищете способ скопировать дерево каталогов в Linux с сохранением символических ссылок (symlinks) на каталоги, но разыменованием символических ссылок на файлы, у вас есть несколько путей решений. Давайте рассмотрим задачу детально и предоставим возможные подходы.

Теория

Стандартные UNIX-утилиты, такие как scp и rsync, предлагают весьма гибкие опции копирования, однако они предусматривают либо полное разыменование всех символических ссылок, либо сохранение их без изменений. Когда вы используете scp -L, все ссылки разыменовываются без исключения. Аналогично, использование rsync с флагами -avHS совместно с --keep-dirlinks или -K приводит к сохранению всех ссылок, включая ссылки на файлы и каталоги.

Пример

Одна из возможных реализаций – более тонкий подход с использованием Python и его библиотеки shutil. В рамках этой библиотеки функция shutil.copytree может быть адаптирована для удовлетворения ваших требований. Вы можете скопировать файлы, игнорируя символические ссылки на каталоги, а затем вручную воссоздать сами ссылки.

import os
import shutil

def copydir_with_symlinks(src, dst):
    symlinks_to_dirs = []

    def ignore_func(dir, contents):
        ignored = []
        for item in contents:
            path = os.path.join(dir, item)
            if os.path.islink(path) and os.path.isdir(path):
                symlinks_to_dirs.append((item, os.readlink(path)))
                ignored.append(item)
        return ignored

    shutil.copytree(src, dst, symlinks=False, ignore=ignore_func)

    # Recreate symlinks to directories
    for target, linkname in symlinks_to_dirs:
        os.symlink(linkname, os.path.join(dst, target))

# Использование функции
source_directory = '/path/to/source'
destination_directory = '/path/to/destination'
copydir_with_symlinks(source_directory, destination_directory)

Применение

Сначала функция ignore_func определяет символические ссылки на каталоги и игнорирует их содержимое при копировании с помощью shutil.copytree. После выполнения основной копии, функция воссоздает сохранённые символические ссылки для директорий в целевой директории.

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

Если вам более привычен Perl, вы можете рассмотреть возможность адаптации предлагаемого скрипта Рэндалла Шварца из статьи "Cleaning up a symlink mess" для ваших нужд.

Эти решения помогут вам справиться с задачей и учесть все тонкости работы с символическими ссылками в Linux, сохраняя высокие стандарты профессиональной работы.

Оцените материал
Добавить комментарий

Капча загружается...