Проблема с командой установки для копирования всего каталога

16

Итак, у меня есть репозиторий с некоторыми из моих конфигурационных файлов, и я пытаюсь создать их makefileдля установки в homedir. У меня проблема в том, что когда я запускаю следующую команду прямо в Bash

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

казалось бы, ничего не происходит в то время как

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

работает как задумано.

Почему не работает первое (более простое и понятное) решение?

nathdwek
источник
Я просто использовал cp с -r. Я действительно не понимаю, почему при установке нет опции -r, как у cp.
Ибрагим

Ответы:

7

Из взгляда на справочную страницу , кажется, что installне будет делать то, что вы хотите.

Действительно, раздел «Синопсис» указывает на использование формы:

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

и позже, страница руководства говорит:

-d, --directory
обрабатывать все аргументы как имена каталогов; создать все компоненты указанных каталогов

Поэтому мне кажется, что смысл этой опции в том, чтобы иметь возможность установить сложную (но пустую) структуру каталогов mkdir -p ....

Вы можете сделать то, что вы хотите с помощью цикла:

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

Или, если есть много уровней ниже /path/to/DotFiles/dir, вы можете использовать find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Джозеф Р.
источник
Создать все компоненты указанных каталогов = Создать подкаталоги, но не файлы?
nathdwek
@nathdwek Верно. Таким образом, вы можете создать сложную (скелетную) структуру каталогов, скажем, в вашем домашнем каталоге, используяinstall -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +не будет работать, по крайней мере, на некоторых (все? большинство?) версиях Linux. Может работать на OSX или что-то. Использовать что-то вроде этого довольно просто, если вы хотите использовать oneliner: 1. создавать рекурсивные каталоги: for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; done2. создавать рекурсивные файлы:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Джош М.
6

Начиная с ответа @Joseph R., это мое решение, чтобы заставить его работать с find, так как я не мог заставить его команду работать. (Я не думаю, что это так из-за правил, применимых к \+: после {}элемента ничего не может быть .) (Я не мог комментировать. Весь этот абзац может быть фактически удален.)

Чтобы скопировать все файлы в один и тот же каталог (здесь target/directory):

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

-D здесь не является обязательным, он просто создаст несуществующие каталоги для цели.

Чтобы скопировать всю иерархию каталогов и ее файлы (при этом пустые каталоги будут опущены), начиная с того места, где вы сейчас находитесь:

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

Как сказано, это воссоздает дерево, начиная с $PWD. Кроме того, если вам нужно скопировать пустой каталог, вы можете найти способ с помощью -type dof findи install -d.

Итак, для того, чтобы скопировать дерево, начиная с каталога, который не является $PWD:

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

Обратите внимание, как parent/directoryне копируется.

дополнительный

Для тех shell/fish, кто использует , вот строка, которая делает то же самое:

fish -c 'cd parent/directory; and find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \\;'
Vrakfall
источник