différence copier le dossier de contenu entre /. et / * sous linux

8

pour copier le contenu d'un dossier que j'ai lu, l'utilisation est la suivante:

cp -rfva ../foldersource/. ./

mais ça marche aussi

cp -rfva ../foldersource/* ./

y a-t-il une différence?

par exemple si je veux supprimer un contenu d'un dossier avec. :

rm -rf ../foldersource/.

je reçois l'erreur:

rm:  rejet delete folder '.' or '..':

mais avec un astérisque c'est ok

rm -rf ../foldersource/*

donc, l'astérisque est de meilleures options qui fonctionnent n'importe où?

stackdave
la source

Réponses:

10

Il existe une différence fondamentale entre ces deux formes d'argument. Et c'est important de comprendre ce qui se passe.

Avec ../foldersource/.l'argument est passé inchangé à la commande, que ce soit cpou rmou autre chose. C'est à la commande que le point de fin ait une sémantique spéciale ou unique différente de la convention Unix standard de simplement pointer vers le répertoire dans lequel il réside; les deux rmet cpsemblent le traiter comme un cas spécial.

Avec ../foldersource/*l'argument est d'abord développé par le shell avant même que la commande ne soit exécutée et ne passe les arguments. Ainsi, rmne voit jamais ../foldersource/*; il voit la version étendue ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1et ainsi de suite. Ceci est important car les systèmes d'exploitation limitent le nombre d'arguments pouvant être passés à une commande, généralement seulement quelques centaines.

eestrada
la source
4
It's up to the command whether that trailing dot makes any senseUm, le point est toujours lié au répertoire contenant lui-même, ../foldersource/.il ne devrait donc pas être différent de l'indication ./foldersource/et en fait c'est juste une manière redondante de déclarer la même chose. Aucune commande n'essaie de «donner un sens» au point ou au double point, car ceux-ci sont standard sur les systèmes de fichiers Linux / Unix. rmrejette simplement la suppression du répertoire de travail actuel comme jimmijindiqué dans leur réponse. Notez également que vous utilisez ./dans tous vos exemples pendant qu'OP ../y est. Un peu (grande) différence.
Sergiy Kolodyazhnyy
"cp -rfva ../foldersource/. ./" est équivalent à "cp -rfva ../foldersource ./", je veux copier le contenu du dossier, mais pas la racine du dossier
stackdave
1
@Stackdave no, cp -rfva ../foldersource/. ./ n'est PAS équivalent à cp -rfva ../foldersource ./ . Le suivi /.est important
roaima
2
Bien que ce que dit cette réponse soit correct, il manque une différence très importante comme mentionné dans la réponse de @ roaima: la variante / * ne copie pas (généralement) les fichiers ou répertoires commençant par.
Adam
@SergiyKolodyazhnyy Vous avez raison; la .est une convention standard sous Unix pour désigner le courant directement. Aussi, merci d'avoir souligné que j'avais utilisé ./dans mes exemples quand j'aurais dû utiliser ../; Je vais arranger ça. Vous avez tort de savoir si les commandes «donnent un sens» au point de fin; comme le fait remarquer l'OP (et je l'ai expérimenté cp) à la fois rmet cpse comportent différemment quand une fuite .est présente. J'aurais dû écrire quelque chose comme "c'est à la commande si le point de fin a une sémantique spéciale ou unique". Je vais changer ma réponse pour plus de clarté.
eestrada
10

Lorsque vous copiez à l'aide de, cp -a source/* target/vous copiez la plupart des fichiers et répertoires de sourceà target. Plus précisément, les éléments exclus seront probablement des fichiers commençant par un point ( .) au niveau supérieur de source.

Considérez ces fichiers (ou répertoires) dans source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will not be copied

Lorsque vous copiez à l'aide de, cp -a source/. target/vous copiez l'intégralité du contenu de source, y compris les éléments commençant par un point ( .) verstarget

Considérez ces fichiers (ou répertoires) dans source

apple        # will be copied
banana/      # will be copied, as will all its contents
.cherry      # will be copied

Si vous utilisez bash, zshvous pouvez utiliser l' dotgloboption pour modifier la signification de *afin qu'il inclue les fichiers et les répertoires commençant par un point (a yashégalement une dotgloboption; cependant, il inclut ensuite .et ..dans les extensions globales ce qui limite son utilisation. Voir aussi FIGNORE='@(.|..)'dans ksh93).

Fait intéressant, il cp -a source/. target/est garanti de ne jamais créer le composant target/source. (D'un autre côté, cp -a source target/cela fera l'une des deux choses selon qu'il targetexiste déjà ou non . Voir Comment copier un dossier de manière récursive de manière idempotente en utilisant cp pour les détails.)


Lorsque vous supprimez avec, rm -rf source/*vous supprimez les fichiers et répertoires sourcequi ne commencent pas par un point ( .). Sous réserve du dotglobparamètre que j'ai déjà mentionné. Il ne supprimera pas le répertoire sourcelui-même.

Lorsque vous essayez de supprimer en utilisant rm -rf source/.il échouera - comme d' autres l'ont déjà expliqué - parce que POSIX interdit la suppression d'un chemin dont le dernier composant est .ou ... L'équivalent le plus proche est rm -rf source, qui supprimera le sourcerépertoire et tout son contenu, qu'ils commencent ou non par un point ( .).

roaima
la source
1
Voir aussi 'rm. *' Supprime-t-il jamais le répertoire parent? d' rm -rf .échouer .
Stéphane Chazelas
7

Vous ne pouvez pas le faire rm -rf ../foldersource/.car rmcela ne le permet pas, comme indiqué explicitement dans le manuel:

Toute tentative de suppression d'un fichier dont le dernier composant du nom de fichier est '.' ou '..' est rejeté sans aucune invite, comme mandaté par POSIX.

et dans le manuel POSIX, man 1p rmnous voyons:

Si l'un des fichiers point ou point-point est spécifié comme la partie de nom de base d'un opérande (c'est-à-dire le composant de nom de chemin final) ou si un opérande se résout dans le répertoire racine, rm doit écrire un message de diagnostic sur l'erreur standard et ne rien faire plus avec de tels opérandes.

jimmij
la source