Il existe une différence fondamentale entre ces deux formes d'arguments. Et il est important de comprendre ce qui se passe.
Avec ../foldersource/.
l'argument est passé tel quel à la commande, qu'il s'agisse de cp
ou rm
ou autre chose. C'est à la commande de décider si ce point final a 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 rm
et cp
semblent le traiter comme un cas particulier.
Avec ../foldersource/*
l'argument est d'abord développé par le shell avant la commande est toujours exécutée et passe tous les arguments. Ainsi, rm
ne voit jamais ../foldersource/*
; il voit la version étendue ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1
etc. Ceci est important car les systèmes d'exploitation limitent le nombre d'arguments pouvant être passés à une commande, généralement quelques centaines seulement.
Lorsque vous copiez en utilisant cp -a source/* target/
vous copiez la plupart des fichiers et répertoires de source
au 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 en utilisant cp -a source/. target/
vous copiez tout le contenu de source
, y compris tous les éléments commençant par un point (.
) à target
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
, zsh
, vous pouvez utiliser le dotglob
possibilité de changer la signification de *
afin qu'il inclue les fichiers et répertoires commençant par un point (yash
a aussi un dotglob
option; cependant, il inclut alors .
et ..
dans les extensions globales, ce qui limite sa convivialité. Voir aussi FIGNORE='@(.|..)'
en ksh93
).
Fait intéressant, cp -a source/. target/
est garanti jamais pour créer le composant target/source
. (En revanche, cp -a source target/
fera l'une des deux choses selon que target
existe déjà. Voir Comment copier un dossier récursivement de manière idempotente en utilisant cp pour les détails.)
Lorsque vous supprimez en utilisant rm -rf source/*
vous supprimez les fichiers et répertoires dans source
qui ne commencent pas par un point (.
). Soumis au dotglob
paramètre que j'ai déjà mentionné. Il ne supprimera pas le répertoire source
lui-même.
Lorsque vous essayez de supprimer en utilisant rm -rf source/.
cela échouera - comme d'autres l'ont déjà expliqué - car POSIX interdit la suppression d'un chemin dont le dernier composant est .
ou ..
. L'équivalent le plus proche est rm -rf source
, ce qui supprimera le source
répertoire et tout son contenu, qu'il commence ou non par un point (.
).
Vous ne pouvez pas faire rm -rf ../foldersource/.
car rm
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ée sans aucune invite, comme l'exige POSIX.
et dans le manuel POSIX man 1p rm
on voit :
Si l'un des fichiers point ou point-point est spécifié comme la partie du nom de base d'un opérande (c'est-à-dire le composant du 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 de plus avec ces opérandes .