- Копирование большого количества файлов из одного каталога в другой в Linux
- 7 ответов
- Оптимальная команда Linux для копирования большого количества файлов
- Как быстро скопировать 400 Гб мелких файлов в куче каталогов или смонтировать два одинаковых LVM
- Быстро перенести(скопировать) мегадиректорию
- Команда cp: правильное копирование папок с файлами в *nix
- Выводы
- Послесловие
Копирование большого количества файлов из одного каталога в другой в Linux
У меня есть каталог, содержащий около 280 000 файлов. Я хочу переместить их в другой каталог.
Если я использую cp или mv затем я получаю слишком длинный список аргументов с ошибкой.
Если я пишу скрипт вроде
, то из-за команды ls ее производительность ухудшается.
Как я могу это сделать?
7 ответов
(обратите внимание на трейлинг /s)
Примечание. Если это длительная операция, и вы хотите увидеть некоторые признаки прогресса во время копирования, вы можете либо добавить опцию -v (verbose) который затем перечисляет все скопированные файлы или рассматривает возможность использования опции —progress для получения более точного результата выполнения.
Мне не хватает двух твитов в ответах здесь, поэтому я добавляю еще один.
Хотя это напоминает мне о добавлении еще одного стандартного ответа .
Здесь есть две проблемы:
У меня есть каталог, содержащий около 280 000 файлов.
Большинство инструментов не масштабируют все это с таким количеством файлов. Не только большинство инструментов Linux или Windows-инструментов, но и множество программ. И это может включать вашу файловую систему. Долгосрочное решение было бы «ну, не делай этого тогда». Если у вас разные файлы, но они в разных каталогах. Если не ожидайте, что в будущем проблемы начнутся.
Сказав это, давайте перейдем к вашей реальной проблеме:
Если я использую cp или mv, я получаю слишком длинный список аргументов с ошибкой
Это вызвано расширением * оболочкой. Оболочка имеет ограниченное пространство для результата и заканчивается. Это означает, что любая команда с —- +: = 0 =: + —- , расширенная оболочкой, будет работать с той же проблемой. Вам нужно либо увеличить количество вариантов одновременно, либо использовать другую команду.
Одна альтернативная команда, используемая часто, когда вы сталкиваетесь с этой проблемой, — это —- +: = 1 =: + —- . Уже есть несколько ответов, показывающих, как их использовать, поэтому я не буду повторять все это. Однако я хотел бы указать разницу между —- +: = 2 =: + —- и —- +: = 3 =: + — — , так как это может сделать огромную разницу в производительности и хорошо вписаться в предыдущее объяснение расширения.
Найти все файлы в пути /в /search /и выполнить команду с ним, но обратите внимание на цитаты вокруг —- +: = 5 =: + —- . Это передает команду * команде. Если бы мы не инкапсулировали его или не убежали, то оболочка попыталась бы расширить его, и мы получим ту же ошибку.
Наконец, я хочу упомянуть что-то о <>. Эти скобки заменяются содержимым, найденным find. Если вы закончите команду с помощью символа semicolom —- +: = 6 =: + —- (тот, который вам нужно убежать из оболочки, следовательно —- +: = 7 =: + —- в примерах), тогда результаты передаются один за другим. Это означает, что вы выполните команды 280000 mv. Один для каждого файла. Это может быть медленным.
В качестве альтернативы вы можете завершить —- +: = 8 =: + —- . Это даст как можно больше аргументов одновременно. Если bash может обрабатывать 2000 аргументов, тогда find /path -name «* filetype» -exec some_move <> + вызовет команду some_move около 140 раз, каждый раз с 2000 аргументами. Это более эффективно (читайте: быстрее).
Источник
Оптимальная команда Linux для копирования большого количества файлов
Это тема, на которую я не смог найти однозначного ответа, или, по крайней мере, один с хорошим объяснением того, почему одно решение лучше другого. Допустим, у меня есть два локальных диска, один с файлами для копирования, один пустой. Обратная связь не обязательна, но оптимальная производительность с несколькими оговорками.
- Структура файла с одной точки вниз должна быть согласованной. Например, файлы могут храниться в каталоге, в x котором x он находится /my_drive_a/to_copy/files/x/ — однако, когда я копирую его /my_drive_b/ , я бы хотел, чтобы он был структурирован только /files/ снизу. Так что результат может выглядеть примерно так /my_drive_b/files/x/ .
- Передача файлов не будет одинаковой каждый раз, поэтому подобная функция rsync может не иметь преимуществ перед подобной функцией cp .
- Количество файлов будет в тысячах, хотя все они небольшие.
- Данные должны быть скопированы и сохранены my_drive_a .
Моя первоначальная мысль будет просто делать cp -R /my_drive_a/to_copy/files/x/ /my_drive_b/files/x/ . Опять же, имея ограниченный опыт работы с функциями копирования в Linux, я не уверен, является ли это оптимальным решением для копирования такого большого количества файлов.
Просто иди с cp . coreutils хорошо оптимизированы и будут работать отлично. За исключением —archive флага, рассмотрите возможность использования —sparse=never , если вы прогнозируете, что нет редких файлов. Это затмит cp и сэкономит время.
Почему нет rsync ? Он попытается проанализировать файлы, отсортировать их (см. «ПОРЯДОК СОРТИРОВКИ ПЕРЕДАЧИ» man rsync ), и будет очень сложно распечатать полезную информацию о ходе работы, не создавая серьезных препятствий для всего процесса. Хотя некоторые из его параметров могут быть отключены, некоторые являются обязательными и приведут к замедлению времени выполнения.
В зависимости от размера ваших данных может быть быстрее скопировать весь диск (например /dev/sda ) с помощью программ, таких как dd или ddrescue , но трудно сказать, когда эта опция будет быстрее.
Источник
Как быстро скопировать 400 Гб мелких файлов в куче каталогов или смонтировать два одинаковых LVM
Сейчас запустил rsync —progress -av /input/folder /outputfolder Только что добавил ещё —exclude-from ‘файл со списков *директорый*’ Скорость копирвоания мелких файлов 10-200 кб/с, Что очень мало.
Думал скопировать побайтово командой dd, но не уверен что получится, так как: df -h /dev/mapper/group-data 660G 347G 280G 56% /home (откуда) /dev/vdb5 379G 131G 230G 37% /mnt (куда) Смущает факт, что при побайтовом, файлы могут быть разбросаны по всей длине /dev/mapper/group-data 660G, и в итоге не поместятся на /dev/vdb5 379G.
Подскажите как максимально быстро их скопировать?
Итоговая цель задачи: После обновления Zentyal, перестала нормально работать самба, невозможность записи(недостаточно места), открытия(недостаточно прав), и невозможность настроить(вылетает). Восстановил из бэкапа машину, но нужно скопировать свежеизмененные файлы.
Разделы на машине в LVM. И подключив к одной машине оба диска, второй выдает ошибку, уже не помню какую. Поэтому решил копировать рсинком.
Если кто то подскажет как мне смонтировать в востановленной машине /dev/mapper/group-data со старой машины, вместо восстановленного, буду благодарен. Итак имеем, vda (new), vdb (old). Старый диск просто скопирован и подключен к виртуалке. Метки и идентификаторы, значит диски имеют одинаковые.. Ибо это один и тот же диск. Как мне примонтировать диск со старой машины в востановленную?
Источник
Быстро перенести(скопировать) мегадиректорию
Есть папка. В ней 160 гиг мелкого 1-2 килобайтного файла + немереянно вложенных папок.
Нада скопировать на другой сервер. Быстро.
Подмонтировал на сервер с файлом папку с пустого сервера через нфс.
В восемь вечера пустил в скрине копировать. В семь утра зашел — копирует до сих пор.
Есть варианты как можно быстро скопировать?
Через ssh: там, откуда копировать, запускаем gzip и передачу файлов через трубу, там, куда копировать, раззиповываем.
А вообще, странно, что так медленно.
По сети? 160 гигов? Ну сутки будет копировать, мб больше. Хочешь быстро — езжай к удаленному компу, выдергивай винт и тащи его к себе.
что значит через gzip? на файловом серваке запаковать и перелить на пустой файл?
200 гиг мускульных дампов по гигу — перелились по сети за шесть часов.
это для примера.
хотят тут наверно долго изза мелкого размера файла
Чего тут странного, если
160 гиг мелкого 1-2 килобайтного файла
На файл-сервере запаковываете, но выхлоп gzip’а идет не в файл, а по ssh туда, куда надо это скопировать. Там, соответственно, на выходе трубы распаковывается. Недостаток: если сеть накроется, придется все копировать снова.
пример можете показать? а что если чесно не понимаю как это сделать.
Ты упоротый? Я тебе уже говорил копируй на уровне блочного устройства (drbd) или lvm-snapshot + ssh + dd или (лоровские задроты считают что LVM-ненужен) делай dd + ssh + fsck
поднимать drbd ради одного копирований?
Не шлангуй. drbd был предложен в теме «каждые 15 минут синхронизировать >250 миллионов файлов»
1. lvm-snapshot —> dd | ssh dd
2. нет LVM —> dd | ssh dd; fsck
Ему не нужно копировать раздел целиком. Да и от этого есть смысл, лишь в случае, когда раздел почти полностью забит. А во всех остальных случаях лучше всего — tar over ssh.
Насколько мне известно, nfs работает через udp, то есть у тебя нет гарантии что все файлы доехали корректно. На сеть другой нагрузки в это время не было?
Насколько мне известно, nfs работает через udp, то есть у тебя нет гарантии что все файлы доехали корректно.
Гарантия есть: либо файлы доехали корректно, либо не доехали.
Если при передаче одного файла в середине было потеряно несколько пакетов, то как об этом узнает команда cp?
Ему не нужно копировать раздел целиком.
В случае с мелкими файлами копирование раздела целиком может оказаться быстрее копирования всех файлов по отдельности. Чтобы не копировать незанятые места раздела, можно вместо dd использовать partclone или partimage. Но проделывать такие фокусы нужно с отмонтированным разделом, иначе ФС может перенестись битой.
Если при передаче одного файла в середине было потеряно несколько пакетов, то как об этом узнает команда cp?
Команда cp об этом узнает от соответствующего системного вызова, системный вызов от VFS, VFS от драйвера NFS, а драйвер NFS узнает о потере из пропущенных номеров пакетов или неправильной контрольной суммы (я не знаю точно какой именно там способ, но он однозначно есть).
И вообще, TCP тоже работает поверх «ненадёжного» протокола IP, но целостность потока там тем не менее гарантируется =).
Неверное планирование не освобождает от титула «дебил». Проекты с таким кол-вом файлов не распологают в директории на /, впрочем ЛОРовская школота с криками «LVM не нужен» и «достаточно / и /home» может теперь жевать свои мозоли.
А ты сначала подумай сколько времени займет просто прочитать с диска
150.000.000 метаданных файлов, а потом и сами файлы — время копирования по сети можно будет не учитывать.
Уже пару-тройку лет по умолчанию nfs в линуксе через tcp.
А так, udp пакет имеет аналогичную tcp контрольную сумму, а повторную передачу пакетов организовывал уже сам nfs. Не помню, чтобы у меня были проблемы с передачей файлов по nfs по udp по 10 Мбит коксиальному кабелю.
Источник
Команда cp: правильное копирование папок с файлами в *nix
В этой статье будут раскрыты некоторые неочевидные вещи связанные с использованием wildcards при копировании, неоднозначное поведение команды cp при копировании, а также способы позволяющие корректно копировать огромное количество файлов без пропусков и вылетов.
Допустим нам нужно скопировать всё из папки /source в папку /target.
Первое, что приходит на ум это:
Сразу исправим эту команду на:
Ключ -a добавит копирование всех аттрибутов, прав и добавит рекурсию. Когда не требуется точное воспроизведение прав достаточно ключа -r .
После копирования мы обнаружим, что скопировались не все файлы — были проигнорированы файлы начинающиеся с точки типа:
.profile
.local
.mc
и тому подобные.
Почему же так произошло?
Потому что wildcards обрабатывает shell ( bash в типовом случае). По умолчанию bash проигнорирует все файлы начинающиеся с точек, так как трактует их как скрытые. Чтобы избежать такого поведения нам придётся изменить поведение bash с помощью команды:
Чтобы это изменение поведения сохранилось после перезагрузки, можно сделать файл wildcard.sh c этой командой в папке /etc/profile.d (возможно в вашем дистрибутиве иная папка).
А если в директории-источнике нет файлов, то shell не сможет ничего подставить вместо звёздочки, и также копирование завершится с ошибкой. Против подобной ситуации есть опции failglob и nullglob . Нам потребуется выставить failglob , которая не даст команде выполниться. nullglob не подойдёт, так как она строку с wildcards не нашедшими совпадения преобразует в пустую строку (нулевой длины), что для cp вызовет ошибку.
Однако, если в папке тысячи файлов и больше, то от подхода с использованием wildcards стоит отказаться вовсе. Дело в том, что bash разворачивает wildcards в очень длинную командную строку наподобие:
На длину командной строки есть ограничение, которое мы можем узнать используя команду:
Получим максимальную длину командной строки в байтах:
Получим что-то типа:
Итак, давайте будем обходиться вовсе без wildcards.
Давайте просто напишем
И тут мы столкнёмся с неоднозначностью поведения cp . Если папки /target не существует, то мы получим то, что нам нужно.
Однако, если папка target существует, то файлы будут скопированы в папку /target/source.
Не всегда мы можем удалить заранее папку /target, так как в ней могут быть нужные нам файлы и наша цель, допустим, дополнить файлы в /target файлами из /source.
Если бы папки источника и приёмника назывались одинаково, например, мы копировали бы из /source в /home/source, то можно было бы использовать команду:
И после копирования файлы в /home/source оказались бы дополненными файлами из /source.
Такая вот логическая задачка: мы можем дополнить файлы в директории-приёмнике, если папки называются одинаково, но если они отличаются, то папка-исходник будет помещена внутрь приёмника. Как скопировать файлы из /source в /target с помощью cp без wildcards?
Чтобы обойти это вредное ограничение мы используем неочевидное решение:
Те кто хорошо знаком с DOS и Linux уже всё поняли: внутри каждой папки есть 2 невидимые папки «.» и «..», являющиеся псевдопапками-ссылками на текущую и вышестоящие директории.
- При копировании cp проверяет существование и пытается создать /target/.
- Такая директория существует и это есть /target
- Файлы из /source скопированы в /target корректно.
Итак, вешаем в жирную рамочку в своей памяти или на стене:
Поведение этой команды однозначно. Всё отработает без ошибок вне зависимости от того миллион у вас файлов или их нет вовсе.
Выводы
Если нужно скопировать все файлы из одной папки в другую, не используем wildcards, вместо них лучше использовать cp в сочетании с точкой в конце папки-источника. Это скопирует все файлы, включая скрытые и не завалится при миллионах файлов или полном отсутствии файлов.
Послесловие
vmspike предложил аналогичный по результату вариант команды:
ВНИМАНИЕ: регистр буквы T имеет значение. Если перепутать, то получите полную белиберду: направление копирования поменяется.
Благодарности:
Источник