Problem z poleceniem instalacji, aby skopiować cały katalog

16

Mam więc repozytorium z niektórymi moimi plikami konfiguracyjnymi i próbuję utworzyć plik, makefileaby zainstalować je w homedir. Problemem jest to, że kiedy uruchamiam następujące polecenie prosto w bash

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

pozornie nic się nie dzieje

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

działa zgodnie z przeznaczeniem.

Dlaczego pierwsze (łatwiejsze i czystsze) rozwiązanie nie działa?

nathdwek
źródło
Właśnie użyłem cp z -r. Naprawdę nie rozumiem, dlaczego instalacja nie ma opcji -r jak cp.
ibrahim,

Odpowiedzi:

7

Spojrzenie na stronę podręcznika pokazuje, że installnie zrobi tego, co chcesz.

Rzeczywiście sekcja Synopsis wskazuje użycie formularza:

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

a później strona man mówi:

-d, --directory
traktuje wszystkie argumenty jak nazwy katalogów; utwórz wszystkie komponenty określonych katalogów

Wydaje mi się więc, że celem tej opcji jest możliwość zainstalowania skomplikowanej (ale pustej) struktury katalogów à la mkdir -p ....

Możesz osiągnąć to, co chcesz za pomocą pętli:

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

Lub, jeśli jest wiele poziomów poniżej /path/to/DotFiles/dir, możesz użyć find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Joseph R.
źródło
Utwórz wszystkie składniki określonych katalogów = Utworzyć podkatalogi, ale nie pliki?
nathdwek
@nathdwek Right. W ten sposób możesz stworzyć złożoną (szkieletową) strukturę katalogów w, powiedzmy, katalogu domowym, używającinstall -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +nie zadziała, przynajmniej nie na niektórych (wszystkich? najbardziej?) wersjach systemu Linux. Może działać na OSX lub coś takiego. Używanie czegoś takiego jest dość proste, jeśli chcesz oneliner: 1. twórz katalogi rekurencyjne: for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; done2. twórz pliki rekurencyjne:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Josh M.
6

Począwszy od odpowiedzi @Josepha R., jest to moje rozwiązanie, aby działało z find, ponieważ nie mogłem sprawić, by jego polecenie działało. (Nie sądzę, żeby tak było, ponieważ obowiązują zasady \+: po {}elemencie nie może być niczego .) (Nie mogłem komentować. Cały ten akapit można faktycznie usunąć.)

Aby skopiować wszystkie pliki do dokładnie tego samego katalogu (tutaj target/directory):

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

-D nie jest tutaj obowiązkowe, po prostu utworzy nieistniejące katalogi do celu.

Aby skopiować całą hierarchię katalogów i jej pliki (spowoduje to pominięcie pustych katalogów), zaczynając od miejsca, w którym aktualnie się znajdujesz:

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

Jak powiedziano, odtworzy to drzewo, zaczynając od $PWD. Również, jeśli chcesz skopiować pustego katalogu na mogłyby znaleźć sposób używając -type dof finda install -d.

Aby więc skopiować drzewo, zaczynając od katalogu, który nie jest $PWD:

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

Zauważ, że parent/directorynie jest kopiowane.

Dodatkowy

Dla tych shell/fish, którzy używają , oto linia, która robi to samo:

fish -c 'cd parent/directory; and find directory/tree/to/copy -type f -exec install -Dm 755 "{}" "target/directory/{}" \\;'
Vrakfall
źródło