Cette réponse révèle que l'on peut copier tous les fichiers - y compris ceux cachés - d'un répertoire src
à l'autre dest
comme ceci:
mkdir dest
cp -r src/. dest
Il n'y a aucune explication dans la réponse ou ses commentaires pour expliquer pourquoi cela fonctionne réellement, et personne ne semble trouver non plus de documentation à ce sujet.
J'ai essayé quelques trucs. Tout d'abord, le cas 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
Puis, avec /.
à la fin:
$ 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
Ainsi, cela se comporte de la même manière *
, mais copie également les fichiers cachés.
$ 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
.
et ..
sont des liens physiques appropriés, comme expliqué ici , tout comme l'entrée de répertoire elle-même.
D'où vient ce comportement et où est-il documenté?
cp
référence explique clairement commentcp -R
fonctionne..
et..
sont des répertoires comme tous les autres répertoires, ils n'ont rien de magique ou de mystérieux..
et..
ne se comportent pas comme les autres répertoires.Réponses:
Le comportement est un résultat logique de l'algorithme documenté pour
cp -R
. Voir POSIX , étape 2f:.
et..
sont des répertoires, respectivement le répertoire actuel et le répertoire parent. Aucun n'est spécial en ce qui concerne le shell, donc aucun n'est concerné par l'expansion, et le répertoire sera copié, y compris les fichiers cachés.*
, d'autre part, sera étendu à une liste de fichiers, et c'est là que les fichiers cachés sont filtrés.src/.
est le répertoire courant à l'intérieursrc
, qui estsrc
lui - même;src/src_dir/..
estsrc_dir
le répertoire parent de, qui l'est encoresrc
. Donc de l'extérieursrc
, sisrc
est un répertoire, spécifiantsrc/.
ousrc/src_dir/..
comme fichier source pourcp
sont équivalents, et copiez le contenu desrc
, y compris les fichiers cachés.Le point de préciser
src/.
est qu'il échouera s'ilsrc
ne s'agit pas d'un répertoire (ou d'un lien symbolique vers un répertoire), alorssrc
qu'il ne le serait pas. Il copiera également le contenu desrc
seulement, sans se copiersrc
; cela correspond aussi à la documentation:Copie donc
cp -R src/. dest
le contenu desrc
dansdest/.
(le fichier source est.
dedanssrc
), tandis quecp -R src dest
copie le contenu desrc
dansdest/src
(le fichier source estsrc
).Une autre façon de penser est de comparer la copie
src/src_dir
etsrc/.
, plutôt que de comparersrc/.
etsrc
..
se comporte commesrc_dir
dans le premier cas.la source
src
copiera le répertoire dansdest
,src/.
copiera le contenu. Je vais essayer de clarifier cela dans la question.src/.
etsrc/*
(notez passrc/.*
);src/*
n'inclut pas les fichiers cachés si la globalisation les ignore ...src
contient évidemment,src/.
mais cela signifie que le répertoire contenant un répertoire dépend de la façon dont vous nommez le répertoire. Bien sûr, l'existence des.
liens signifie que tous les répertoires se contiennent, mais cela peut ne pas être intuitif pour tous. Au lieu de ce comportement, on pourrait également être tenté de supposer que "le répertoire contenant le répertoirefoo
" serait déterminé parfoo/..
, auquel cas cela n'aurait pas d'importance si nous nous référions àfoo
oufoo/.
: le répertoire contenant résultant serait le même.foo
etfoo/.
semble un peu délicate, mais ça ne me dérange pas, je trouve aussi ça un peu amusant.Lorsque vous courrez
cp -R src/foo dest
, vous obtiendrezdest/foo
. Donc, si le répertoiredest/foo
n'existe pas,cp
le créera, puis copiera le contenu desrc/foo
dansdest/foo
.Lorsque vous exécutez
cp -R src/. dest
,cp
voit quedest/.
existe, et il est juste la question de copier le contenusrc/.
àdest/.
.Lorsque vous le considérez comme la copie d'un répertoire nommé à
.
partir desrc
et la fusion de son contenu avec le répertoire existantdest/.
, cela aura du sens.la source