Незважаючи на те, що це запитання та прийнята відповідь давні, я додаю свою відповідь, оскільки існуючі в даний час питання, які використовують cp
або не обробляють деякі крайні випадки, або вимагають інтерактивної роботи. Часто крайні випадки / сценарій / переносимість / кілька джерел не мають значення, проте в такому випадку простота перемагає, і краще використовувати cp
безпосередньо меншу кількість прапорців (як в інших відповідях), щоб зменшити когнітивне навантаження - але для тих інших часів (або для надійно використовуваної функції) це виклик / функція корисна і, до речі, не є специфічною для bash (я розумію, що це питання стосувалося bash, тому це просто бонус у цьому випадку). Деякі прапори можуть бути скороченими (наприклад, з -a
), але я включив усі явно у довгій формі (за винятком-R
, див. нижче) для пояснення. Очевидно, просто видаліть будь-які прапори, якщо є якась функція, яка вам конкретно не потрібна (або ви перебуваєте в не-posix ОС, або ваша версія cp
не обробляє цей прапор - я протестував це на GNU coreutils 8.25's cp
):
mergedirs() {
_retval=0
_dest="$1"
shift
yes | \
for _src do
cp -R --no-dereference --preserve=all --force --one-file-system \
--no-target-directory "${_src}/" "$_dest" || { _retval=1; break; }
done 2>/dev/null
return $_retval
}
mergedirs destination source-1 [source-2 source-3 ...]
Пояснення:
-R
: має незначно відмінну семантику від -r
/ --recursive
на деяких системах (особливо щодо спеціальних файлів у вихідних папках), як пояснюється у цій відповіді
--no-dereference
: ніколи не переходьте за символічними посиланнями у ДЖЕРЕЛІ
--preserve=all
: зберегти вказані атрибути (за замовчуванням: режим, право власності, позначки часу), якщо можливо, додаткові атрибути: контекст, посилання, xattr, усі
--force
: якщо існуючий файл призначення не вдається відкрити, видаліть його та повторіть спробу
--one-file-system
: залишайтеся в цій файловій системі
--no-target-directory
: Лікувати DEST як звичайний файл (пояснено в цій відповіді , а саме: If you do a recursive copy and the source is a directory, then cp -T copies the content of the source into the destination, rather than copying the source itself.
)
- [введення з трубопроводу
yes
]: навіть з --force
, у цьому конкретному рекурсивному режимі cp
все ще запитується перед обробкою кожного файлу, тому ми досягаємо неінтерактивності, виводячи трубопровід yes
до нього
- [виведення в трубопроводі
/dev/null
]: це для того, щоб замовкнути безладну низку запитань у напрямкуcp: overwrite 'xx'?
- [return-val & ранній вихід]: це забезпечує вихід циклу, як тільки
1
є помилкова копія, і повернення, якщо сталася помилка
ДО:
- Новий прикольний прапор, який я також використовую з цим у своїй системі, - це
--reflink=auto
робити так звані "легкі копії" (copy-on-write, з тими самими перевагами швидкості, що і жорсткі посилання, і тими ж перевагами розміру до і у зворотній пропорції наскільки файли розходяться в майбутньому). Цей прапор прийнятий в останній GNU cp
і робить більше, ніж не застосовувати сумісні файлові системи на останніх ядрах Linux. YMWV-багато в інших системах.
cp -r html_new/* html
? Після цього можна видалитиhtml_new
каталог.