Скопировать структуру папок linux

Команда 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 в очень длинную командную строку наподобие:

cp -a /souce/a /source/b /source/c …… /target

На длину командной строки есть ограничение, которое мы можем узнать используя команду:

Читайте также:  Virtualbox linux virtual machines

Получим максимальную длину командной строки в байтах:

…. Maximum length of command we could actually use: 2089314 ….

Итак, давайте будем обходиться вовсе без 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 в сочетании с точкой в конце папки-источника. Это скопирует все файлы, включая скрытые и не завалится при миллионах файлов или полном отсутствии файлов.

Читайте также:  Sed linux примеры замены

Послесловие

vmspike предложил аналогичный по результату вариант команды:

ВНИМАНИЕ: регистр буквы T имеет значение. Если перепутать, то получите полную белиберду: направление копирования поменяется.
Благодарности:

  • Компании RUVDS.COM за поддержку и возможность публикации в своем блоге на Хабре.
  • За изображение TripletConcept. Картинка очень большая и детальная, можно открыть в отдельном окне.

Источник

Скопировать структуру папок linux

Собственно хочется скопировать на другой диск полную структуру одного каталога, в нем примерно тысяча подкаталогов. Собственно нужна только структура, файлики сами не нужны.
Есть ли какая команда?

>
>Собственно хочется скопировать на другой диск полную структуру одного каталога, в нем
>примерно тысяча подкаталогов. Собственно нужна только структура, файлики сами не нужны.
>
>Есть ли какая команда?

какой нить язык + какая нить рекурсивная функция

find -type d даст тебе список каталогов, а создавать можешь как душе угодно — хоть xargs mkdir с нужым параметром, хоть файло после парсить со списком этих каталогво.

>
>Собственно хочется скопировать на другой диск полную структуру одного каталога, в нем
>примерно тысяча подкаталогов. Собственно нужна только структура, файлики сами не нужны.
>
>Есть ли какая команда?

find /where/to/search -type d | cpio -pvdm /where/to/copy

>>
>>Собственно хочется скопировать на другой диск полную структуру одного каталога, в нем
>>примерно тысяча подкаталогов. Собственно нужна только структура, файлики сами не нужны.
>>
>>Есть ли какая команда?
>
>
>find /where/to/search -type d | cpio -pvdm /where/to/copy

СПАСИБО! все так и сделал, все ОК 🙂

Удалить Правка | Высказать мнение | Ответить | Рекомендовать в FAQ | Cообщить модератору | Наверх


Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ]
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.

Читайте также:  Линукс забыл пароль root

Источник

How to copy in bash all directory and files recursive?

SourceDir contains also sub-folders. Problem that in DestFolder not only all tree, but in up level all another levels and files. How to fix ?

4 Answers 4

cp -r ./SourceFolder ./DestFolder 

So, to clarify, capital -R option will copy the root dir again; small -r option keeps the root paths the same.

cp is not a bash command but a separate executable, so it is system-specific. True bash commands on the other hand are the same across operating systems.

I had to add a slash at the end of my source folder. Not sure why. I was using build vars too. cp -r «$CONFIG_PATH/» «$CODESIGNING_FOLDER_PATH»

cp -r ./SourceFolder ./DestFolder 

code for a copy with success result

cp -rv ./SourceFolder ./DestFolder 

code for Forcefully if source contains any readonly file it will also copy

cp -rf ./SourceFolder ./DestFolder 

also try this cp -r ./dist/* ./out ;

this command will copy dist/* files to out dir;

@SherylHohman It’s different because he put a /* on the end of the source folder. I don’t know why that matters though.

this response instead of copying the entire folder copies content of the source folder into the destination (./out) folder

You might find it handy to keep your attributes set

cp -arf ./SourceFolder ./DestFolder

cp -arf . throws the error «cp: the -R and -r options may not be specified together.» Changing it to cp -af . solves it. I’m not sure if it’s a typo on your end of if cp -arf . actually worked for you, but I hope this helps in case anyone is getting the same error. Reference: stackoverflow.com/a/32695418/5810737

Источник

Оцените статью
Adblock
detector