Незважаючи на те, що це запитання та прийнята відповідь давні, я додаю свою відповідь, оскільки існуючі в даний час питання, які використовують 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каталог.