Problem mit dem Installationsbefehl zum Kopieren eines ganzen Verzeichnisses

16

Also habe ich ein Repo mit einigen meiner Konfigurationsdateien und ich versuche ein zu erstellen makefile, um sie im Homedir zu installieren. Das Problem, das ich habe, ist, dass, wenn ich den folgenden Befehl gerade in Bash ausführe

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

scheinbar passiert dabei nichts

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

funktioniert wie vorgesehen.

Warum funktioniert die erste (einfachere und sauberere) Lösung nicht?

Nathdwek
quelle
Ich habe gerade cp mit -r verwendet. Ich verstehe wirklich nicht, warum die Installation nicht die Option -r hat, die cp hat.
Ibrahim

Antworten:

7

Ein Blick auf die Manpage zeigt , dass installdas nicht das tut, was Sie wollen.

In der Tat gibt der Abschnitt "Synopsis" eine Verwendung des Formulars an:

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

und später sagt die Manpage:

-d, --directory Behandelt
alle Argumente als Verzeichnisnamen. Erstellen Sie alle Komponenten der angegebenen Verzeichnisse

Daher scheint es mir der Sinn dieser Option zu sein, eine komplizierte (aber leere) Verzeichnisstruktur à la installieren zu können mkdir -p ....

Sie können mit einer Schleife das erreichen, was Sie wollen:

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

Oder, wenn es unter viele Ebenen gibt /path/to/DotFiles/dir, können Sie Folgendes verwenden find:

find /path/to/DotFiles/dir/ -type f -exec 'install -m 755 "{}" ~/' +
Joseph R.
quelle
Alle Komponenten der angegebenen Verzeichnisse erstellen = Die Unterverzeichnisse aber nicht die Dateien erstellen?
Nathdwek
@nathdwek Richtig. Auf diese Weise können Sie eine komplexe (Skelett-) Verzeichnisstruktur beispielsweise unter Ihrem install -m 755 -d ~/foo/bar/baz
Joseph R.
1
-exec 'install -m 755 "{}" ~/' +wird nicht funktionieren, zumindest nicht auf bestimmten (alle? die meisten?) version von linux. Kann unter OSX oder so funktionieren. Die Verwendung von so etwas ist ziemlich einfach, wenn Sie einen Oneliner möchten: 1. Verzeichnisse rekursiv for d in $(find . -type d); do install -d --mode 755 "$d" "../install-test/$d"; doneerstellen : 2. Dateien rekursiv erstellen:for f in $(find . -type f); do install -D --mode 644 "$f" ../install-test/; done
Josh M.
6

Ausgehend von der Antwort von @Joseph R. ist dies meine Lösung, damit es mit find funktioniert, da ich sein Kommando nicht zum Laufen bringen konnte. (Ich glaube nicht, weil die Regeln für ... gelten\+ : Nach dem {}Element darf nichts stehen .) (Ich konnte keinen Kommentar abgeben. Dieser ganze Absatz kann tatsächlich entfernt werden.)

So kopieren Sie alle Dateien in genau dasselbe Verzeichnis (hier target/directory):

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

-D ist hier nicht zwingend erforderlich, es werden nur die nicht vorhandenen Verzeichnisse zum Ziel angelegt.

So kopieren Sie eine ganze Verzeichnishierarchie und ihre Dateien (dabei werden leere Verzeichnisse weggelassen) von Ihrem aktuellen Standort aus:

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

Wie gesagt, wird hierdurch der Baum neu erstellt, beginnend mit $PWD. Auch wenn Sie das leere Verzeichnis kopieren müssen, könnte on eine Möglichkeit finden, das -type dvon zu verwendenfind undinstall -d .

Um den Baum zu kopieren, gehen Sie also von einem Verzeichnis aus, das nicht $PWD:

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

Beachten Sie, wie parent/directorynicht kopiert wird.

Extra

Für diejenigen shell/fish, die es benutzen , ist hier die Zeile, die dasselbe tut:

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