Frage

sah ich folgende interessante Nutzung von Teer in ein Bash-Skripte Mitarbeiter:

`tar cf - * | (cd <dest> ; tar xf - )`

Offensichtlich funktioniert es ähnlich wie rsync -aV tut, aber schneller. Stellt sich die Frage, wie?

-m


Bearbeiten : Kann mir jemand erklären Warum sollte diese Lösung über die folgenden vorzuziehen?

cp -rfp * dest

Ist der ehemalige schneller?

War es hilfreich?

Lösung

Auf dem Unterschied zwischen cp und Teer der Verzeichnishierarchien, ein einfaches Experiment kopieren kann durchgeführt werden, um den Unterschied zu zeigen:

alastair box:~/hack/cptest [1134]% mkdir src
alastair box:~/hack/cptest [1135]% cd src
alastair box:~/hack/cptest/src [1136]% touch foo
alastair box:~/hack/cptest/src [1137]% ln -s foo foo-s
alastair box:~/hack/cptest/src [1138]% ln foo foo-h
alastair box:~/hack/cptest/src [1139]% ls -a
total 0
-rw-r--r--  2 alastair alastair    0 Nov 25 14:59 foo
-rw-r--r--  2 alastair alastair    0 Nov 25 14:59 foo-h
lrwxrwxrwx  1 alastair alastair    3 Nov 25 14:59 foo-s -> foo
alastair box:~/hack/cptest/src [1142]% mkdir ../cpdest
alastair box:~/hack/cptest/src [1143]% cp -rfp * ../cpdest
alastair box:~/hack/cptest/src [1144]% mkdir ../tardest
alastair box:~/hack/cptest/src [1145]% tar cf - * | (cd ../tardest ; tar xf - )
alastair box:~/hack/cptest/src [1146]% cd ..
alastair box:~/hack/cptest [1147]% ls -l cpdest
total 0
-rw-r--r--  1 alastair alastair    0 Nov 25 14:59 foo
-rw-r--r--  1 alastair alastair    0 Nov 25 14:59 foo-h
lrwxrwxrwx  1 alastair alastair    3 Nov 25 15:00 foo-s -> foo
alastair box:~/hack/cptest [1148]% ls -l tardest
total 0
-rw-r--r--  2 alastair alastair    0 Nov 25 14:59 foo
-rw-r--r--  2 alastair alastair    0 Nov 25 14:59 foo-h
lrwxrwxrwx  1 alastair alastair    3 Nov 25 15:00 foo-s -> foo

Der Unterschied liegt in den hart verknüpfte Dateien. Beachten Sie, wie die hart verknüpfte Dateien kopiert werden einzeln mit cp und zusammen mit tar. Um den Unterschied deutlicher zu machen, haben einen Blick auf die Inodes für jeden:

alastair box:~/hack/cptest [1149]% ls -i cpdest
24690722 foo  24690723 foo-h  24690724 foo-s
alastair box:~/hack/cptest [1150]% ls -i tardest
24690801 foo  24690801 foo-h  24690802 foo-s

Es gibt wahrscheinlich andere Gründe Teer zu bevorzugen, aber dies ist ein großer, zumindest wenn man ausgiebig hart verknüpfte Dateien hat.

Andere Tipps

Es schreibt das Archiv auf die Standardausgabe, dann Rohre an einen Subprozess - von den Klammern eingewickelt -, dass Änderungen in einem anderen Verzeichnis und liest / Auszüge aus der Standardeingabe. Das ist, was der Strich Zeichen nach dem f Argumente bedeutet. Es ist im Grunde das Kopieren alle sichtbaren Dateien und Unterverzeichnisse des aktuellen Verzeichnisses in ein anderes Verzeichnis.

Für ein Verzeichnis mit 25.000 leeren Dateien:

$ time { tar -cf - * | (cd ../bar; tar -xf - ); }
real    0m4.209s
user    0m0.724s
sys 0m3.380s

$ time { cp * ../baz/; }
real    0m18.727s
user    0m0.644s
sys 0m7.127s

Für ein Verzeichnis mit 4-Dateien von 1073741824 Bytes (1 GB), die jeweils

$ time { tar -cf - * | (cd ../bar; tar -xf - ); }
real    3m44.007s
user    0m3.390s
sys 0m25.644s

$ time { cp * ../baz/; }
real    3m11.197s
user    0m0.023s
sys 0m9.576s

Meine Vermutung ist dieses Phänomen sehr Dateisystem-abhängig ist. Wenn ich mich nicht irre werden Sie einen drastischen Unterschied zwischen einem Dateisystem sehen, die in zahlreichen kleinen Dateien, wie ReiserFS 3.6 und ein Dateisystem, das auf dem Umgang mit großen Dateien ist besser spezialisiert hat.

(lief ich die oben genannten Tests auf HFS +).

Dies ist eine einmalige Verwendung von Rohren. Im Grunde genommen, in der Regel die erste tar schreibt direkt in eine Datei, sondern es wird auf der Standardausgabe schreiben (die -), die dann auf den anderen Teer umgeleitet wird, die stdin anstatt auf einer Datei erfolgt. Im Grunde ist dies das gleiche wie in eine Datei Teer und entpacken später, mit der Ausnahme, ohne die Datei zwischendurch.

Das Power Buch hat die Kopie als:

tar cf - * | (cd <dest> && tar xvBf - )

Die ‚&&‘ ist eine Bedingung, die den Rückgabecode des vorhergehenden Befehls überprüft. Ihat heißt, wenn die „cd“ nicht bestanden, der „tar xf -“ nicht ausgeführt werden. Ich werfe immer in einem -v (ausführlich) und -B (reblock Eingang).

I tar die ganze Zeit. Es ist besonders nützlich für das Kopieren auf ein anderes System, wie zum Beispiel:

tar cvf -. | ssh jemand @ somemachine '(cd irgendwo && tar xbf -)

tar cf - * | (cd <dest> ; tar xf - )

wird alle nicht versteckten Dateien / Verzeichnisse des aktuellen Verzeichnisses auf die Standardausgabe Teer, dann, dass Rohrleitungen in ein neues Subshells' stdin. Das Shell ändert sich zunächst das aktuelle Arbeitsverzeichnis <dest> und dann untars es in dieses Verzeichnis.

Einige alten Versionen von cp haben nicht f / p (und ähnliche) Optionen für die Berechtigungen zu bewahren, so dass dieser tar Trick hat den Job.

Ich glaube, dass der Teer wird ein Windows-Stil ‚fusionieren‘ Betrieb mit tief verschachtelten Verzeichnissen tun, während der cp Unterverzeichnisse werden überschrieben.

Zum Beispiel, wenn Sie das Layout:

dir/subdir/file1

und kopieren Sie es zu einem Ziel, das enthält:

dir/subdir/file2

Dann mit Kopie Sie wird links mit:

dir/subdir/file1

Aber mit dem Befehl tar, Ihr Ziel enthalten:

dir/subdir/file1
dir/subdir/file2
tar cf - *

Dieses verwendet tar * senden an stdout

|

Dies macht die offensichtliche Umleitung von stdout ...

(cd <dest> ; tar xf - )

Dieses, das PWD an die entsprechende Stelle ändert und extrahiert dann aus stdin

Ich weiß nicht, warum dies schneller als rsync wäre, da es keine Kompression beteiligt ist.

Die Teer-Lösung wird symbolische Links bewahren, während cp wird nur Kopien machen und die Links zerstören.

Teer war viel länger als rsync ein Standard-Unix-Dienstprogramm. Du bist eher es in einer Situation zu finden, wenn eine Verzeichnishierarchie an eine andere Stelle kopiert werden muss (auch ein anderer Computer). rsync ist wahrscheinlich einfacher, diese Tage zu benutzen, ist aber langsamer, da es sowohl die Quelle und Ziele und Synchronisierung der sie vergleicht. Teer nur Kopien in eine Richtung.

Wenn Sie GNU cp haben (die alle Linux-basierten Systemen wird), wird die cp --archive arbeiten, auch an schwer verknüpften Dateien und Teer ist nicht erforderlich.

Wie es passiert, ein Mitarbeiter hat einen nahezu identischen Befehl in ein unserem Skripte. Nachdem ich einige Zeit rätselhaft über sie verbrachte, fragte ich, warum er das nicht cp benutzt hatte. Seine Antwort, wie ich mich erinnere, war, dass cp langsam ist, wenn Sie eine Kopie von einem Dateisystem in einem anderen.

Ob dies wahr ist, würde mehr Tests erfordern, als ich auf die Frage zu verbringen pflegen, aber es macht einen gewissen Sinn. Der erste tar Prozess liest aus dem Quellgerät so schnell wie nur möglich warten, dass das Gerät zu lesen. Inzwischen liest der zweite Prozeß tar von seinem Eingangsrohr und möglichst schnell schreibt. Es könnte für die Eingabe warten müssen, aber wenn schreibt auf dem Zielgerät ist langsamer als auf dem Quellgerät liest es wird nur auf dem Zielgerät warten. Ein einzelner cp Befehl wird sowohl von der Quelle und den Zielgeräten warten müssen.

Auf der anderen Seite, moderne Betriebssysteme machen einen ziemlich guten Job von pre-Caching IO-Operationen. Es ist durchaus möglich, cp wird die meiste Zeit beim Schreiben wartet verbringen und immer aus dem Speicher liest, anstatt das Gerät selbst. Es scheint wie ein wirklich brauchen solide Daten würden mit zwei tar Befehle anstatt den einfacheren cp Befehl zu wählen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top