Cette réponse révèle que l'on peut copier tous les fichiers - y compris ceux cachés - à partir de répertoire src
dans le répertoire dest
comme:
mkdir dest
cp -r src/. dest
Il n'y a pas d'explication dans la réponse ou ses commentaires sur la raison pour laquelle cela fonctionne réellement, et personne ne semble trouver de la documentation à ce sujet non plus.
J'ai essayé quelques choses. Premièrement, 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
Ensuite, 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
Donc, cela se comporte similitant à *
, mais copie également des 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 matériels appropriés comme expliqué ici , comme l'entrée de l'annuaire elle-même.
D'où vient ce comportement et où est-ce documenté?
Le comportement est un résultat logique de l'algorithme documenté pour cp -R
. Voir [~ # ~] posix [~ # ~ ~] , étape 2f:
Les fichiers du répertoire Source_file doivent être copiés dans le répertoire DEST_FILE , Prenant les quatre étapes (1 à 4) énumérés ici avec les fichiers comme Source_files .
.
et ..
sont des répertoires, respectivement le répertoire actuel et le répertoire parent. Ni sont spéciales aussi loin que la coquille ne sont concernées, donc non plus d'expansion, et le répertoire sera copié, y compris des fichiers cachés. *
, D'autre part, sera étendu à une liste de fichiers, ce qui sera là où les fichiers cachés sont filtrés.
src/.
est le répertoire actuel à l'intérieur src
, qui est src
lui-même; src/src_dir/..
est src_dir
Le répertoire parent, qui est à nouveau src
. Donc, de l'extérieur src
, si src
est un répertoire, spécifiant src/.
ou src/src_dir/..
Comme le fichier source de cp
sont équivalents et copiez le contenu de src
, y compris des fichiers cachés.
Le point de spécifier src/.
Est-ce que cela échouera si src
n'est pas un répertoire (ou un lien symbolique à un répertoire), alors que src
ne le ferais pas. Il copiera également le contenu de src
uniquement, sans copier src
lui-même; Cela correspond aussi à la documentation:
Si cible existe et nomme un répertoire existant, le nom du chemin de destination correspondant pour chaque fichier dans la hiérarchie de fichier doit être la concaténation de cible , un seul caractère SLASH si la cible ne s'est pas terminée dans une barre oblique, et le chemin du fichier relatif au répertoire contenant Source_file .
Donc cp -R src/. dest
copie le contenu de src
à dest/.
(le fichier source est .
dans src
), alors que cp -R src dest
copie le contenu de src
à dest/src
(le fichier source est src
).
Une autre façon d'en penser est de comparer la copie src/src_dir
et src/.
, plutôt que de comparer src/.
et src
. .
se comporte comme src_dir
dans le cas précédent.
Quand vous courez cp -R src/foo dest
, tu auras dest/foo
. Donc si répertoire dest/foo
n'existe pas, cp
_ va le créer, puis copier le contenu de src/foo
à dest/foo
.
Quand vous courez cp -R src/. dest
, cp
voit que dest/.
existe, puis c'est juste la question de copier le contenu de src/.
à dest/.
.
Lorsque vous y pensez, copier un répertoire nommé .
de src
et fusionner son contenu avec le répertoire existant dest/.
, ça aura un sens.