Esta respuesta revela que uno puede copiar todos los archivos, incluidos los ocultos, del directorio src
al directorio de la siguiente dest
manera:
mkdir dest
cp -r src/. dest
No hay una explicación en la respuesta o en sus comentarios sobre por qué esto realmente funciona, y nadie parece encontrar documentación sobre esto tampoco.
Probé algunas cosas. Primero, el caso normal:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src dest
$ ls -A dest
dest_file src
Luego, con /.
al final:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/. dest
$ ls -A dest
dest_file .dotfile src_dir src_file
Entonces, esto se comporta de manera similar a *
, pero también copia archivos ocultos.
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/* dest
$ ls -A dest
dest_file src_dir src_file
.
y ..
son enlaces duros adecuados como se explica aquí , al igual que la entrada del directorio en sí.
¿De dónde viene este comportamiento y dónde está documentado?
cp
referencia explica claramente cómocp -R
funciona..
y..
son directorios como cualquier otro directorio, no hay nada mágico o misterioso en ellos..
, y..
no se comportan como otros directorios.Respuestas:
El comportamiento es un resultado lógico del algoritmo documentado para
cp -R
. Ver POSIX , paso 2f:.
y..
son directorios, respectivamente, el directorio actual y el directorio padre. Ninguno de los dos es especial en lo que respecta al shell, por lo que ninguno se preocupa por la expansión, y el directorio se copiará, incluidos los archivos ocultos.*
, por otro lado, se expandirá a una lista de archivos, y aquí es donde se filtran los archivos ocultos.src/.
es el directorio actual dentrosrc
, que es ensrc
sí mismo;src/src_dir/..
essrc_dir
el directorio padre, que es nuevamentesrc
. Entonces, desde afuerasrc
, sisrc
es un directorio, especificarsrc/.
osrc/src_dir/..
como el archivo fuentecp
es equivalente y copiar el contenido desrc
, incluidos los archivos ocultos.El punto de especificar
src/.
es que fallará sisrc
no es un directorio (o enlace simbólico a un directorio), mientrassrc
que no lo haría. También copiará el contenido desrc
solo, sin copiarse asrc
sí mismo; esto también coincide con la documentación:Entonces
cp -R src/. dest
copia el contenido desrc
todest/.
(el archivo fuente está.
ensrc
), mientras quecp -R src dest
copia el contenido desrc
todest/src
(el archivo fuente estásrc
).Otra forma de pensar en esto es comparar la copia
src/src_dir
ysrc/.
, en lugar de compararsrc/.
ysrc
..
se comporta comosrc_dir
en el primer caso.fuente
src
copiará el directoriodest
,src/.
copiará el contenido. Trataré de aclarar eso en la pregunta.src/.
ysrc/*
(nota, nosrc/.*
);src/*
no incluye archivos ocultos si globbing los ignora ...src
contienesrc/.
pero significa que el directorio que contiene un directorio depende de cómo se nombre el directorio. Por supuesto, la existencia de los.
enlaces de alguna manera significa que todos los directorios se contienen a sí mismos, pero eso podría no ser intuitivo para todos. En lugar de este comportamiento, uno también podría verse tentado a suponer que "el directorio que contiene el directoriofoo
" estaría determinado porfoo/..
, en cuyo caso no importaría si nos referimos afoo
ofoo/.
: el directorio que contiene sería el mismo.foo
yfoo/.
parece un poco delicada, pero no me importa, también me parece un poco divertido.Cuando corras
cp -R src/foo dest
, lo conseguirásdest/foo
. Entonces, si el directoriodest/foo
no existe,cp
lo creará y luego copiará el contenido desrc/foo
adest/foo
.Cuando ejecuta
cp -R src/. dest
,cp
ve quedest/.
existe, y luego es solo cuestión de copiar el contenido desrc/.
adest/.
.Cuando se piensa en ello como copiar un directorio con el nombre
.
desrc
y la fusión de su contenido con el directorio existentedest/.
, tendrá sentido.fuente