Aunque esta pregunta y su respuesta aceptada son antiguas, agrego mi respuesta porque las que existen actualmente que usan cp
o bien no manejan algunos casos extremos o requieren trabajar de forma interactiva. Sin embargo, a menudo no importan los casos de borde/guión/portabilidad/fuentes múltiples, en cuyo caso la simplicidad gana, y es mejor usar cp
directamente con menos banderas (como en otras respuestas) para reducir la carga cognitiva, pero para aquellos otras veces (o para una función robustamente reutilizable) esta invocación/función es útil, y por cierto no es específica de bash (me doy cuenta de que esta pregunta era sobre bash, así que eso es solo una bonificación en este caso). Algunos indicadores se pueden abreviar (por ejemplo, con -a
), pero he incluido todos explícitamente en formato largo (excepto en el -R
, consulte a continuación) por razones de explicación. Obviamente, simplemente elimine cualquier indicador si hay alguna característica que usted no desea desea (o si está en un sistema operativo que no es POSIX, o su versión de cp
no procesa ese indicador - He probado esto en GNU coreutils 8.25 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 ...]
Explicación:
-R
: tiene sutilmente diferentes semántica de -r
/--recursive
en algunos sistemas (en particular con respecto a los archivos especiales en dirs fuente) como se explica en this answer
--no-dereference
: Nunca seguir enlaces simbólicos en FUENTE
--preserve=all
: preservar los atributos especificados (por defecto: modo, propiedad, marcas de tiempo), si es posible, atributos adicionales: contexto, enlaces, xattr, todo
--force
: si una ya existente archivo de destino no se puede abrir, retire y vuelva a intentarlo
--one-file-system
: permanecer en este sistema de archivos
--no-target-directory
: DEST tratar como un archivo normal (explicado en en this answer, a saber: 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.
)
- [entrada de hilo de
yes
]: incluso con --force
, en este modo recursivo particular, cp
todavía pregunta antes clobbering cada archivo, por lo que lograr la no-interactividad mediante la canalización de salida de yes
a ella
- [salida de hilo a
/dev/null
]: este es silenciar la cadena desordenada de preguntas a lo largo de las líneas de cp: overwrite 'xx'?
- [para volver-val & salida temprana]: esto asegura el bucle sale tan pronto como hay una copia fallado, y devuelve
1
si hubo un error
BTW:
- Una nueva bandera cobarde que también utilizo con esto en mi sistema es
--reflink=auto
para hacer llamadas "copias de luz" (copia en escritura, con las mismas ventajas de velocidad como difíciles de vinculación, y el mismo el tamaño beneficia hasta y en proporción inversa a la cantidad de archivos divergentes en el futuro). Esta bandera es aceptada en el reciente GNU cp
, y hace más que un no-op con sistemas de archivos compatibles en kernels recientes de Linux. YMWV-a-lot en otros sistemas.
Probado 'cp -r html_new/* html'? Puede eliminar el directorio 'html_new' luego. – ismail