Quiero crear una "copia" de un árbol de directorios donde cada archivo es un enlace al archivo original
Ejemplo: tengo una estructura de directorio:
dirA/
dirA/file1
dirA/x/
dirA/x/file2
dirA/y/
dirA/y/file3
Aquí está el resultado esperado, una "copia" del árbol de directorios donde cada archivo es un enlace rígido al archivo original:
dirB/            #  normal directory
dirB/file1       #  hardlink to dirA/file1
dirB/x/          #  normal directory
dirB/x/file2     #  hardlink to dirA/x/file2
dirB/y/          #  normal directory
dirB/y/file3     #  hardlink to dirA/y/file3
                
pax, como en FreeBSD,cp -ano enlaza los enlaces simbólicos.POSIXY, usaría
paxen modo lectura + escritura con la-lopción:(
-peConserva todos los atributos posibles de archivos (en este caso sólo directorios) que se copian, como GNUcp's-ahace).Ahora, aunque estándar , ese comando no es necesariamente muy portátil .
Primero, muchos sistemas basados en GNU / Linux no se incluyen
paxpor defecto (a pesar de que es una utilidad POSIX no opcional).Luego, varios errores y no conformidades con algunas implementaciones causan varios problemas con ese código.
pax(al menos) no funciona cuando se usa-rwlen combinación con-s. Por alguna razón, parece que aplica la sustitución tanto a la ruta original como a la copiada. Así que arriba, intentaría hacer algo enlink("dirB/file", "dirB/file")lugar delink("dirA/file", "dirB/file").paxno crea enlaces duros para archivos de tipo enlace simbólico (un comportamiento permitido por POSIX). No solo eso, sino que también aplica la sustitución a los objetivos de los enlaces simbólicos (un comportamiento no permitido por POSIX). Entonces, por ejemplo, si hay unfoo -> AAenlace simbólicodirA, se convertiráfoo -> BAendirB.Además, si desea hacer lo mismo pero con rutas de archivos arbitrarias cuyo contenido está almacenado
$srcy$dst, es importante darse cuenta de quepax -rwl -- "$src" "$dst"crea la estructura de directorio completa de$srcdentro$dst(que tiene que existir y ser un directorio). Por ejemplo, si$srcesfoo/bar, entonces,$dst/foo/barse crea.Si, en cambio, desea
$dstser una copia de$src, lo más fácil es probablemente hacerlo como:(que también solucionaría la mayoría de los problemas mencionados anteriormente, pero fallaría si la ruta absoluta de
$dsttermina en caracteres de nueva línea).Ahora eso no ayudará en los sistemas GNU / Linux donde no hay
pax.Es interesante notar que
paxfue creado por POSIX para fusionar las características de los comandostarycpio.cpioes un comando histórico de Unix (de 1977) en oposición a una invención POSIX, y también hay una implementación de GNU (no unapax). Entonces, aunque ya no es un comando estándar (aunque estaba en SUSv2), sigue siendo muy común y hay un conjunto básico de características en las que generalmente puede confiar.El equivalente de
pax -rwlseríacpio -pl. Sin embargo:cpiotoma la lista de archivos de entrada en stdin en lugar de argumentos (nueva línea delimitada, lo que significa que los nombres de archivo con caracteres de nueva línea no son compatibles)find(findycpiofueron desarrollados conjuntamente por las mismas personas)).cpioimplementaciones tienen opciones para preservar algunas, pero nada portátil).Entonces con
cpio:fuente
-s /A/BreemplazaAconBpara que sedirAconviertadirB. Si el nombre del directorio de origen no tieneA, entonces eso lo copiará (vinculará) sobre sí mismo. Vea también el resto de la respuesta para posibles enfoques mejores.Respuesta corta:
fuente
En caso de que esté buscando esa función de copiar con enlaces duros para hacer instantáneas o copias de seguridad de (todos o parte de) sus archivos, eche un vistazo
rsnapshot.fuente
La respuesta de @ gudmundur-orn es correcta, pero si estás en BtrFS en Linux
cp a --reflink=auto dirA dirBdebería hacer el truco, con la diferencia de que los archivos son realmente diferentes y cambiar uno no cambia el otro. Puede lograr casi lo mismo concp -cuna Mac con APFS (autohará una copia completa si no es posible,-cfallará).Cualquier sistema de archivos COW debería poder hacerlo, pero los proveedores no han acordado una opción de línea de comando estándar.
fuente