Quand j'utilise
cp -R inputFolder outputFolder
le résultat dépend du contexte :
- s'il
outputFolder
n'existe pas, il sera créé et le chemin du dossier cloné seraoutputFolder
. - s'il
outputFolder
existe, le clone créé seraoutputFolder/inputFolder
C'est horrible , car je veux créer un script d'installation. Si l'utilisateur l'exécute deux fois par erreur, il l'aura outputFolder
créé la première fois. À la deuxième exécution, tous les éléments seront créés à nouveau outputFolder/inputFolder
.
- Je veux toujours le premier comportement: créer un clone à côté de l'original (en tant que frère ou soeur).
- Je veux utiliser
cp
pour être portable (par exemple, MINGW n'a pas étérsync
expédié) - J'ai vérifié
cp -R --parents
mais cela recrée le chemin jusqu'au bout de l'arborescence (donc le clone ne sera pasoutputFolder
maissome/path/outputFolder
) --remove-destination
ou si le--update
cas 2 ne change rien, les choses sont encore copiées dansoutputFolder/inputFolder
Est-il possible de le faire sans d'abord vérifier l'existence du outputFolder
(si le dossier n'existe pas alors ...) ou en utilisant rm -rf outputFolder
?
Quel est le moyen UNIX convenu et portable de faire cela?
mv
de déplacer une collection de fichiers dans un seul fichier ordinaire?rsync
?cp
, la canalisation entre deuxtar
commandes est un moyen fiable et agréable de copier des arbres.rsync
expédié.tar -C input -cf - . | tar -C output -xf -
marche.-C
modifie le répertoire de travail, mais ce n’est pas une option standard, donc s’il n’est pas pris en charge, vous devez commencer par exécuter les deux( cd input && tar -cf - . ) | ( cd output && tar -xf - )
fichiers tar dans les répertoires de travail appropriés. Par exemple, si vous utilisez Windows, je n’utiliserai que la réponse de roaima.Réponses:
Utilisez ceci à la place:
Cela fonctionne exactement de la même manière que, par exemple
cp -R aaa/bbb ccc
: si ceccc
n’existe pas, il est créé en tant que copiebbb
et son contenu; mais s'ilccc
existe déjà, ilccc/bbb
est créé en tant que copiebbb
et son contenu.Dans presque tous les cas,
bbb
cela donne le comportement indésirable que vous avez noté dans votre question. Cependant, dans cette situation spécifique, lebbb
est juste.
, doncaaa/bbb
vraimentaaa/.
, ce qui à son tour est vraiment justeaaa
mais sous un autre nom. Nous avons donc ces deux scénarios:ccc
n'existe pas:La commande
cp -R aaa/. ccc
signifie "créerccc
et copier le contenu deaaa/.
dansccc/.
, c.-aaa
à-dccc
. Copier dans .ccc
existe:La commande
cp -R aaa/. ccc
signifie "copier le contenu deaaa/.
dansccc/.
, c.-aaa
à-dccc
. Copier dans .la source
inputFolder/.
au lieu deinputFolder
et en effet cela fonctionne pour moi sur Windows / Git Bash. (Cela ne fonctionne pas cependant avec juste une fin/
, j'ai aussi besoin du point après la barre oblique). J'ai donné +1 car c'est intéressant, même si c'est probablement un peu trop compliqué de l'utiliser en code public :)Ne copiez pas le dossier, copiez seulement le contenu:
De cette façon, vous vous assurez tous les deux que le répertoire cible est créé lors de la première exécution du script et évitez le problème lorsque vous l'exécutez une seconde fois.
Chris Down fait remarquer à juste titre que lors de bash, les fichiers dont le nom commence par un seront ignorés
.
. Pour éviter cela, vous pouvez exécutershopt -s dotglob
avant d’exécuter la commande ci-dessus.Les deux
-p
pourmkdir
et-R
pourcp
sont définies par POSIX ce qui devrait être parfaitement portable.la source
.
. En bash, vous pouvez utiliserdotglob
pour cela.Essayez l'
-T
option pourcp
. Cela existe dans lacp
version 8.22 de GNU coreutils ; il ne peut pas être portable en dehors de cela.la source
cp -T
(cp --no-target-directory
). unix.stackexchange.com/questions/94831/… Malheureusement, ma version decp
est beaucoup plus ancienne.-u
est une excellente option à ajouter pour le rendre paresseux.Vous pouvez aussi utiliser
rsync
:(notez les barres obliques, surtout après le premier)
la source
À mon avis, rien de plus simple et portable
rm -rf outputFolder
. Donc, je m'en tiens toujours à ça. Je comprends que votre question est différente, mais je pense que c'est la meilleure pratique.la source
cp
soit le même, à la fois lorsque le répertoire n'existe pas et quand il existe. Alors qu'est-ce que tu racontes?cp
commande donnée par l'OP ne conserve pas les autorisations (ou les horodatages).Vous pouvez utiliser l'
-t
option decp
commande comme:maintenant, si le dossier cible n'existe pas, une erreur sera générée:
Remarque La commande ci-dessus copiera
inputFolder
avec son contenu (et pas seulement le contenu qu'il contient)si vous ne voulez copier que le contenu,
inputFolder
cela devient un peu compliqué (car vous devez faire attention lorsque vous utilisez un shell globbing tout en utilisant un astérisque *)maintenant, si le dossier cible n'existe pas, une erreur sera générée:
marche avec
cp (GNU coreutils) 8.23
la source