Несмотря на то, что этот вопрос и его принятый ответ являются древними, я добавляю свой ответ, потому что существующие в настоящее время, используя cp
, либо не обрабатывают некоторые крайние регистры, либо требуют интерактивной работы. Часто кросс-кейсы/возможность сценарирования/переносимость/множественные источники не имеют значения, но в этом случае простота выигрывает, и лучше использовать cp
непосредственно с меньшим количеством флагов (как и в других ответах), чтобы уменьшить когнитивную нагрузку, но для них другой раз (или для надежной функции повторного использования) эта функция вызова полезна и, кстати, не является специфичной для bash (я понимаю, что этот вопрос касался bash, так что это просто бонус в этом случае). Некоторые флаги могут быть сокращены (например, с -a
), но я включил все явно в длинную форму (за исключением -R
, см. Ниже) для объяснения. Очевидно, просто удалите любые флаги, если есть какая-то особенность, которую вы конкретно указали не хотите (или вы находитесь в ОС, не относящейся к вам, или ваша версия 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
на некоторых системах (в частности, в отношении специальных файлов в исходных директорий), как описано в this answer
--no-dereference
: никогда не следует символическим ссылкам в ИСТОЧНИКЕ
--preserve=all
: сохранить заданные атрибуты (по умолчанию: режим, право собственности, временные метки), если это возможно дополнительные атрибуты: контекст, ссылки, некоторый атрибут, все
--force
: если существующему файл назначения не может быть открыт, удалите его и попробуйте еще раз
--one-file-system
: остаться на этой файловой системе
--no-target-directory
: лечить DEST как обычный файл (объяснено в this answer, а именно: 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'?
- [возвратного-валина & раннего выхода]: это гарантирует, что цикл выходит, как только есть неудачная копия, и возвращает
1
если произошла ошибка
BTW:
- фанки новый флаг, который я использую с этим на моей системе
--reflink=auto
для выполнения так называемых «легких копий» (копирование при записи, с теми же преимуществами скорости, как жесткий сшиванию, и то же самое до и обратно пропорционально размеру файлов в будущем). Этот флаг принят в недавнем GNU cp
и делает больше, чем нет-op с совместимыми файловыми системами на последних ядрах Linux. YMWV-a-lot в других системах.
Пробовал 'cp -r html_new/* html'? После этого вы можете удалить каталог 'html_new'. – ismail