Копирование содержимого одного каталога в другой

Почему-то не срабатывает команда

cp --recursive --verbose /p/a/t/h/* /t/o/

если в /p/a/t/h/ лежат только скрытые файлы и папки.

Пишет: cp: не удалось выполнить stat для '/p/a/t/h/*': Нет такого файла или каталога

Нужно СОДЕРЖИМОЕ ОДНОГО КАТАЛОГА скопировать в другой.
В инете нашёл способ с добавлением точки.

cp --recursive --verbose /p/a/t/h/. /t/o/

Работает, но я его не понимаю. Он какой-то недокументированный. Ни в хелпе, ни в мане про это ничего не сказано.

Как это всё-таки правильно делать?
rsync попробуйте, еще для него есть шкурка, называется grsync. Он даже линки умеет, и можно включать\выключать рекурсию.
In Tux We Trust
YuraRimskiy
Он какой-то недокументированный. Ни в хелпе, ни в мане про это ничего не сказано
Смотрите "Globbing" вот на русском www.linuxcookbook.ru/books/absguide/ch18s02.html#FTN.AEN12544
cp -r -v /p/a/t/h /t/o
Попробуйте так , /t/o - желательно создать заранее.
"*" - не разыменовывает скрытые(те что начинаются с точки) файлы и каталоги

cp --recursive --verbose 1/* 2
все файлы кроме скрытых копируются из каталога 1 в каталог 2

cp --recursive --verbose 1/.* 2
копируются только скрытые файлы из каталога 1 в каталог 2

cp --recursive --verbose 1/{*,.*} 2
копируются все файлы (скрытые и не скрытые)

YuraRimskiy
Он какой-то недокументированный. Ни в хелпе, ни в мане про это ничего не сказано.
там работает не документация а логика )

"." - также означает и текущий каталог (можно увидеть командой ls -la); к слову, родительский каталог обозначается двумя точками(..)

ваша команда
cp --recursive --verbose 1/. 2
эквивалентна
cp --recursive --verbose 1/./ 2
то есть, вы копируете конкретный каталог - "1/." со всем его содержимым, которое "естественно" копируется в текущий(.) каталог 2

YuraRimskiy
Как это всё-таки правильно делать?
команды
cp --recursive --verbose 1/{*,.*} 2
и
cp --recursive --verbose 1/. 2
эквивалентны (относительно результата) хотя и работают немного по разному
и раз они делают то что от них ожидается то и "правильными" будут они оба )
Под шаблон .* попадут, в том числе, . (текущий каталог) и .. (родительский каталог). Очень не советую так делать.

На самом деле, всё просто :)
1) вместо всех этих --recursive и т.д., используйте cp -a
2) чтобы шаблон * включал в себя "скрытые" файлы и каталоги, нужно просто переключить поведение шаблонов
shopt -s dotglob
cp -a /path/from/* /path/to/
Нет, . и .. под этот шаблон не попадут. Чтобы вернуть нормальное поведение в текущей сессии баша, опцию можно отключить той же командой с ключом -u
shopt -u dotglob

Подробнее об опциях шаблонов баша смотрите, например, тут.
Из других интересных возможностей – можно отключить чувствительность шаблонов к регистру:
shopt -s nocaseglob
ls *.jpg
В этом примере будут выведены файлы, оканчивающиеся и на .jpg, и на .JPG
Как вариант
find -maxdepth 1 -mindepth 1 -exec cp -r {} path/ \;
Текущий и родитель не попадают, только файлы и папки, в т.ч. скрытые. Не знаю, насколько феншуен вариант в целом, но пользовался много раз и без проблем.
Natrio
Под шаблон .* попадут, в том числе, . (текущий каталог) и .. (родительский каталог). Очень не советую так делать.
что попадает, а что не попадает под шаблон при копировании можно легко проверить, для этого и существует параметр --verbose
например:
$ mkdir -p 1/.11 2 && touch 1/{a,.b}
$ tree -a
.
├── 1
│   ├── .11
│   ├── a
│   └── .b
└── 2
скопируем содержимое каталога 1 в 2:
$ cp --recursive --verbose 1/{*,.*} 2
'1/a' -> '2/a'
'1/.11' -> '2/.11'
'1/.b' -> '2/.b'
$ tree -a
.
├── 1
│   ├── .11
│   ├── a
│   └── .b
├── 2
│   ├── .11
│   ├── a
│   └── .b
скорее всего в утилите cp уже заранее учтено то что копировать каталоги . и .. ненужно если это не указанно явно

$ rm -r 2 && mkdir 2
во втором способе мы указали явно копировать каталог .
$ cp --recursive --verbose 1/. 2
'1/./.11' -> '2/./.11'
'1/./a' -> '2/./a'
'1/./.b' -> '2/./.b'
но так как каталог 2/. это тот же каталог 2 то и результат будет одинаков
$ tree -a
.
├── 1
│   ├── .11
│   ├── a
│   └── .b
├── 2
│   ├── .11
│   ├── a
│   └── .b
red
команды

cp –recursive –verbose 1/{*,.*} 2

и

cp –recursive –verbose 1/. 2

эквивалентны (относительно результата) хотя и работают немного по разному
и раз они делают то что от них ожидается то и "правильными" будут они оба )
Большое спасибо,очень мне пригодилось
Linux Forever!
red, уважаю ваше упорство :) Самому на старости лет было тяжело узнать, что поведение шаблонов управляемо.
"Звёздочка" без шаманства захватывает "скрытые" файлы и каталоги, достаточно разрешить ей это: shopt -s dotglob

Ваша гипотеза об автоматическом "выкидывании" . и .. командой cp не оправдывается (тем более, что она получает от баша не шаблоны, а уже раскрытый список путей, явно содержащий все варианты раскрытия):
$ mkdir /tmp/test
$ cd /tmp/test
$ mkdir -p 1/2/3 1/.hid 2
$ touch 1/.h
$ echo 1/{*,.*}
1/2 1/. 1/.. 1/.h 1/.hid
$ cp --recursive --verbose 1/{*,.*} 2
'1/2' -> '2/2'
'1/2/3' -> '2/2/3'
cp: предупреждение: каталог-источник '1/.' указан более одного раза
'1/./.hid' -> '2/./.hid'
'1/./.h' -> '2/./.h'
cp: жёсткая ссылка '2/1' на каталог '2/.' не будет создана
cp: невозможно скопировать каталог '1/..' в самого себя, '2'
'1/.h' -> '2/.h'
пример явно делает много лишнего.

Что касается второго, копирующего 1/. , он действительно работает, хотя и очень неочевидным способом, то есть в данном случае как раз имеет место "костыль" внутри команды cp: путь "каталог/." (формально эквивалентный "каталог" ) воспринимается как указание копировать содержимое вместо самого каталога, если каталог назначения существует (если не существует, всё работает так же, но уже вполне ожидаемо).

P.S.
Кроме того, костыль внутри cp никаки не поможет с другими командами, к примеру mv так уже не умеет:
$ mv -v 1/. 2
mv: невозможно переместить '1/.' в '2/.': Устройство или ресурс занято
Команда scp воспримет "путь/". как эквивалент "путь", и сработает почти как cp, с одним забавным отличием – прежнее содержимое каталога назначения будет уничтожено.
 
Зарегистрироваться или войдите чтобы оставить сообщение.