POSIXY, usaría pax
en modo lectura + escritura con la -l
opción:
pax -rwlpe -s /A/B/ dirA .
( -pe
Conserva todos los atributos posibles de archivos (en este caso sólo directorios) que se copian, como GNU cp
's -a
hace).
Ahora, aunque estándar , ese comando no es necesariamente muy portátil .
Primero, muchos sistemas basados en GNU / Linux no se incluyen pax
por 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.
- debido a un error, Solaris 10
pax
(al menos) no funciona cuando se usa -rwl
en 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 en link("dirB/file", "dirB/file")
lugar de link("dirA/file", "dirB/file")
.
- en FreeBSD,
pax
no 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 un foo -> AA
enlace simbólico dirA
, se convertirá foo -> BA
en dirB
.
Además, si desea hacer lo mismo pero con rutas de archivos arbitrarias cuyo contenido está almacenado $src
y $dst
, es importante darse cuenta de que pax -rwl -- "$src" "$dst"
crea la estructura de directorio completa de $src
dentro $dst
(que tiene que existir y ser un directorio). Por ejemplo, si $src
es foo/bar
, entonces, $dst/foo/bar
se crea.
Si, en cambio, desea $dst
ser una copia de $src
, lo más fácil es probablemente hacerlo como:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(que también solucionaría la mayoría de los problemas mencionados anteriormente, pero fallaría si la ruta absoluta de $dst
termina en caracteres de nueva línea).
Ahora eso no ayudará en los sistemas GNU / Linux donde no hay pax
.
Es interesante notar que pax
fue creado por POSIX para fusionar las características de los comandos tar
y cpio
.
cpio
es 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 una pax
). 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 -rwl
sería cpio -pl
. Sin embargo:
cpio
toma 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)
- Todos los archivos tienen que especificarse (por lo general, se alimenta con la salida de
find
( find
y cpio
fueron desarrollados conjuntamente por las mismas personas)).
- los metadatos no se conservan (algunas
cpio
implementaciones tienen opciones para preservar algunas, pero nada portátil).
Entonces con cpio
:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
pax
, como en FreeBSD,cp -a
no enlaza los enlaces simbólicos.