Problème avec la commande d'installation pour copier un répertoire entier

16

J'ai donc un dépôt avec certains de mes fichiers de configuration et j'essaie de créer un makefilepour les installer dans le homedir. Le problème que j'ai est que lorsque j'exécute la commande suivante directement dans bash

install -m 755 -d ~/path/to/dotfilesDir/ ~/

apparemment rien ne se passe

install -m 755 ~/path/to/dotfilesDir/{file1,file2,...} ~/

fonctionne comme prévu.

Pourquoi la première solution (plus simple et plus propre) ne fonctionne-t-elle pas?

nathdwek
la source
Je viens d'utiliser cp avec -r. Je ne comprends vraiment pas pourquoi l'installation n'a pas l'option -r comme cp.
ibrahim

Réponses:

7

En regardant la page de manuel , il semble que installcela ne fera pas ce que vous voulez.

En effet, la section Synopsis indique une utilisation du formulaire:

install [OPTION]... -d DIRECTORY...

et plus tard, la page de manuel dit:

-d, --directory
traite tous les arguments comme des noms de répertoire; créer tous les composants des répertoires spécifiés

Il me semble donc que l'intérêt de cette option est de pouvoir installer une structure de répertoire compliquée (mais vide) à la mkdir -p ....

Vous pouvez accomplir ce que vous voulez avec une boucle:

for file in /path/to/DotFiles/dir/*;do
    install -m 755 "$file" ~/
done

Ou, s'il y a plusieurs niveaux sous /path/to/DotFiles/dir, vous pouvez utiliser find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Joseph R.
la source
Créer tous les composants des répertoires spécifiés = Créer les sous-répertoires mais pas les fichiers?
nathdwek
@nathdwek À droite. De cette façon, vous pouvez créer une structure de répertoires complexe (squelette) sous, disons, votre répertoire personnel en utilisantinstall -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +ne va pas fonctionner, du moins pas sur certaines (toutes? la plupart?) versions de linux. Peut fonctionner sur OSX ou quelque chose. Utiliser quelque chose comme ça est assez simple si vous voulez un oneliner: 1. créer des répertoires récursifs: for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; done2. créer des fichiers récursifs:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Josh M.
6

À partir de la réponse de @Joseph R., voici ma solution pour le faire fonctionner avec find, car je ne pouvais pas faire fonctionner sa commande. (Je ne pense pas que ce soit le cas, en raison des règles qui s'appliquent à \+: il ne peut rien y avoir après l' {}élément.) (Je ne pouvais pas commenter. Tout ce paragraphe peut en fait être supprimé.)

Pour copier tous les fichiers dans le même répertoire exact (ici target/directory):

find directory/to/copy -type f -exec install -Dm 755 "{}" "target/directory" \;

-D n'est pas obligatoire ici, il créera simplement les répertoires inexistants sur la cible.

Pour copier toute une hiérarchie de répertoires et ses fichiers (cela supprimera les répertoires vides) à partir de l'endroit où vous vous trouvez actuellement:

find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;

Comme dit, cela va recréer l'arbre à partir de $PWD. En outre, si vous avez besoin de copier le répertoire vide, sur pourrait trouver un moyen utilisant le -type dde findet install -d.

Donc, pour copier l'arborescence, à partir d'un répertoire qui n'est pas $PWD:

(cd parent/directory && find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \;)

Remarquez comment parent/directoryn'est pas copié.

Supplémentaire

Pour ceux qui utilisent shell/fish, voici la ligne qui fait de même:

fish -c 'cd parent/directory; and find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \\;'
Vrakfall
la source