Re: find-Frage: Finde nicht-hardlinked Dateien/Verzeichnisse
![](https://seccdn.libravatar.org/avatar/64a6d3479c9e938d9347d134e2fbcb68.jpg?s=120&d=mm&r=g)
Hi Matti Schön dich wieder mal zu lesen..! Am 11.12.2011 15:14, schrieb Matthias Keller:
Hallo Liste
Ich habe für mich nun einen schönen Backup eingerichtet basierend auf hardlinks und rsync. Damit werden bei jedem neuen Backupvorgang nur jeweils die Dateien neu kopiert, die sich geändert haben, alle anderen werden gehardlinkt auf den vorherigen Backup.
Nun möchte ich nachträglich herausfinden, welche Dateien in einem Backup neu hinzu gekommen sind. Dazu müsste dieses Verzeichnis und das vorherige verglichen werden und jene Dateien/Verzeichnisse ausgegeben werden, welche NICHT mit dem vorherigen Backup 'verhardlinkt' sind... Brauchst du unbedingt hardlinks? Mit Symlinks könntest du mit "file" immerhin Symlinks von "richtigen" Dateien (und auch "broken links") unterscheiden..?
Ich weiss, dass ich mit find -samefile oder -inode hardlinks vergleichen kann - aber wie kann ich zwei Verzeichnisse vergleichen und Dateien finden, die NICHT verhardlinkt zum vorherigen sind? Vielleicht würde sich eine kleine (no-)sql Datenbank anbieten die die änderungen nachführt ? So direkt auf Dateiebene sehe ich keinen Weg..
Nur der Hardlink-Count kann ich auch nicht anschauen, weil ev spätere Backups wiederum einen Hardlink auf die Datei gesetzt haben und dieser damit beeinflust sein kann... Ev lässt sich mit einem rsync 'dry run' oder so etwas machen statt mittels find? Bin leider kein rsync-profi..
Vielen Dank für euren Input
Matti
--Tom -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/36545824f598e466583a81e838e79f14.jpg?s=120&d=mm&r=g)
Am 11.12.2011 17:20, schrieb thomas Buehlmann:
Hi Matti
Schön dich wieder mal zu lesen..!
Am 11.12.2011 15:14, schrieb Matthias Keller:
Hallo Liste
Ich habe für mich nun einen schönen Backup eingerichtet basierend auf hardlinks und rsync. Damit werden bei jedem neuen Backupvorgang nur jeweils die Dateien neu kopiert, die sich geändert haben, alle anderen werden gehardlinkt auf den vorherigen Backup.
Nun möchte ich nachträglich herausfinden, welche Dateien in einem Backup neu hinzu gekommen sind. Dazu müsste dieses Verzeichnis und das vorherige verglichen werden und jene Dateien/Verzeichnisse ausgegeben werden, welche NICHT mit dem vorherigen Backup 'verhardlinkt' sind... Brauchst du unbedingt hardlinks? Mit Symlinks könntest du mit "file" immerhin Symlinks von "richtigen" Dateien (und auch "broken links") unterscheiden..?
Ich weiss, dass ich mit find -samefile oder -inode hardlinks vergleichen kann - aber wie kann ich zwei Verzeichnisse vergleichen und Dateien finden, die NICHT verhardlinkt zum vorherigen sind? Vielleicht würde sich eine kleine (no-)sql Datenbank anbieten die die änderungen nachführt ? So direkt auf Dateiebene sehe ich keinen Weg..
Nur der Hardlink-Count kann ich auch nicht anschauen, weil ev spätere Backups wiederum einen Hardlink auf die Datei gesetzt haben und dieser damit beeinflust sein kann... Ev lässt sich mit einem rsync 'dry run' oder so etwas machen statt mittels find? Bin leider kein rsync-profi..
Vielen Dank für euren Input
Matti
--Tom
Hi, mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können... cu jth -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ==== ACHTUNG: Nur als Andeutung des Prinzips gedacht und ungetestet, einfach nur hier in die Mail reingetippert! ==== #!/usr/bin/perl use warnings; use strict; use File::Find; my %files; sub wanted { local $_ = shift; ### 'lstat' weil man kopierte symlinks nicht wie das original ### behandeln will (d.h. man will nicht den inode der Datei auf ### die der symlink zeigt). ### ggfs. noch testen auf Dateiart (normal, link, pipe, device... # my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, # $atime, $mtime, $ctime, $blksize, $blocks ) = lstat($_); my $ino = (lstat($_))[1]; push(@{$files{$ino}}, $File::Find::name); } find( { wanted => \&wanted, follow => 0, bydepth => 1, no_chdir => 1 }, @ARGV ); foreach my $ino (sort keys %files) { ### Dateinamen sortiert nach inode sortiert ausgeben, letztlich ### will man hier aber nach Verzeichnis filtern, aber s.u. bzgl. ### pre-/postprocess foreach( sort @{$files{$ino}} ) { printf("%10i\t%s\n", $ino, $_); } } ==== Man könnte wohl schon im find mit pre-/postprocess die "neuen" Verzeichnisse ausfiltern in denen ma nix finden will, etwa preprocess => sub { return if $File::Find::dir ~ /REGEX_FUER_NEUERES_DATUM_IM_VERZ/; }, bzw. das Gegenteil, return unless $File::Find::dir ~ /REGEX_FUER_AELTERE_VERZ/; oder sowas in der Art. Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten. HTH, -dnh -- I'm -4.50 in each eye and I read in bed with no problems[1]. [1] Not counting the cat wanting my attention on her not the book. -- Stevo -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/36545824f598e466583a81e838e79f14.jpg?s=120&d=mm&r=g)
Am 13.12.2011 09:56, schrieb David Haller:
Hallo,
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ... Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten.
HTH, -dnh
nix gegen perl, das ich viel zu wenig kann und schon gar nicht gegen David ;-), aber ich sehe eigentlich keine Notwendigkeit zu rekursiven ls. Mein Ansatz wäre, zwei Dateien mit ls -i zu erzeugen und die dann zu vergleichen, mit ein bißchen sort [-u] und grep sollte da was zu machen sein. Sicher muss man die diversen Optionen für die Gestaltung des Outputs von ls auch mal ansehen, ls ist ja berühmt für die Zahl seiner Optionen ;-) Das geht sicher schneller, als perl zu lernen (auch, wenn David sagen wird, dass man ohne perl eigentlich gar nicht richtig linuxen kann ;-) und es ist auch eine nette bash-Fingerübung. cu jth -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/3b88186bea83a1e6f8dc1e8959e80e75.jpg?s=120&d=mm&r=g)
Jörg Thümmler schrieb:
Am 13.12.2011 09:56, schrieb David Haller:
Hallo,
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ... Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten.
HTH, -dnh
nix gegen perl, das ich viel zu wenig kann und schon gar nicht gegen David ;-), aber ich sehe eigentlich keine Notwendigkeit zu rekursiven ls.
Mein Ansatz wäre, zwei Dateien mit ls -i zu erzeugen und die dann zu vergleichen, mit ein bißchen sort [-u] und grep sollte da was zu machen sein. Sicher muss man die diversen Optionen für die Gestaltung des Outputs von ls auch mal ansehen, ls ist ja berühmt für die Zahl seiner Optionen ;-) Das geht sicher schneller, als perl zu lernen (auch, wenn David sagen wird, dass man ohne perl eigentlich gar nicht richtig linuxen kann ;-) und es ist auch eine nette bash-Fingerübung.
comm eignet sich hervorragend zum Vergleich zweier Dateien. Zitat aus der manpage: "With no options, produce three-column output. Column one contains lines unique to FILE1, column two contains lines unique to FILE2, and column three contains lines common to both files." Bernd Helmholtz Zentrum München Deutsches Forschungszentrum für Gesundheit und Umwelt (GmbH) Ingolstädter Landstr. 1 85764 Neuherberg www.helmholtz-muenchen.de Aufsichtsratsvorsitzende: MinDir´in Bärbel Brumme-Bothe Geschäftsführer: Prof. Dr. Günther Wess und Dr. Nikolaus Blum Registergericht: Amtsgericht München HRB 6466 USt-IdNr: DE 129521671 -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/638c5f9b9a41e53d4663197a58261c49.jpg?s=120&d=mm&r=g)
Hallo, Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
Am 13.12.2011 09:56, schrieb David Haller:
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ... Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten.
nix gegen perl, das ich viel zu wenig kann und schon gar nicht gegen David ;-), aber ich sehe eigentlich keine Notwendigkeit zu rekursiven ls.
Es geht um ein Backup mit rsync/rsnapshot o.ä. ... Das wird sicher nicht nur eine Verzeichnisebene haben ...
Mein Ansatz wäre, zwei Dateien mit ls -i zu erzeugen und die dann zu vergleichen, mit ein bißchen sort [-u] und grep sollte da was zu machen sein.
Rekursiv? Ein Alptraum.
Sicher muss man die diversen Optionen für die Gestaltung des Outputs von ls auch mal ansehen, ls ist ja berühmt für die Zahl seiner Optionen ;-)
Nö. ls nich.
Das geht sicher schneller, als perl zu lernen (auch, wenn David sagen wird, dass man ohne perl eigentlich gar nicht richtig linuxen kann ;-) und es ist auch eine nette bash-Fingerübung.
Ja, es ginge in bash. Aber es wird so komplex, daß es idiotisch scheint. Rekursiv find/ls -i, sort, comm tralala ... Das ist keine Fingerübung mehr, das ist purer Masochismus. Widerleg mich, wenn du dich traust. Nur zu. Will ich sehen! Nur ein Ansatz wie meine Perl Variante reichte mir für's erste sogar! Du bist dran, -dnh -- C ist übel hardwareabhängig und auch wieder nicht. Die Designer sind, glaube ich, den einfachsten Weg für die Implementierung gegangen. Wir abstrahieren die Hardware da, wo es uns Spaß macht und für den Fall, dass wir keinen Spaß hatten, da machen wir den Zugriff wenigstens kaputt. -- O. Schad -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/36545824f598e466583a81e838e79f14.jpg?s=120&d=mm&r=g)
Am 13.12.2011 13:43, schrieb David Haller:
Hallo,
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
Am 13.12.2011 09:56, schrieb David Haller:
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ... Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten.
nix gegen perl, das ich viel zu wenig kann und schon gar nicht gegen David ;-), aber ich sehe eigentlich keine Notwendigkeit zu rekursiven ls.
Es geht um ein Backup mit rsync/rsnapshot o.ä. ... Das wird sicher nicht nur eine Verzeichnisebene haben ...
Mein Ansatz wäre, zwei Dateien mit ls -i zu erzeugen und die dann zu vergleichen, mit ein bißchen sort [-u] und grep sollte da was zu machen sein.
Rekursiv? Ein Alptraum.
Sicher muss man die diversen Optionen für die Gestaltung des Outputs von ls auch mal ansehen, ls ist ja berühmt für die Zahl seiner Optionen ;-)
Nö. ls nich.
Das geht sicher schneller, als perl zu lernen (auch, wenn David sagen wird, dass man ohne perl eigentlich gar nicht richtig linuxen kann ;-) und es ist auch eine nette bash-Fingerübung.
Ja, es ginge in bash. Aber es wird so komplex, daß es idiotisch scheint. Rekursiv find/ls -i, sort, comm tralala ... Das ist keine Fingerübung mehr, das ist purer Masochismus. Widerleg mich, wenn du dich traust. Nur zu. Will ich sehen! Nur ein Ansatz wie meine Perl Variante reichte mir für's erste sogar!
Du bist dran, -dnh
OK, jetzt hab ich ein bißchen Zeit: find <dir1> -ls >l1 find <dir2> -ls >>l1 sort -u -k1,1 >l2 in l2 stehen alle Dateien, die keine gleichen Inodes haben, also keine hardlinks sind, das kann ich jetzt nach dem gewünschten <dir>, von dem ich das wissen will, greppen. Da sort -u immer die 2. Zeile löscht, ist es natürlich logisch, dass <dir1> das Verzeichnis ist, wo ich die Namen wissen möchte... grep "<dir1>" <l2 sollte es tun. So im groben mal... cu jth -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/36545824f598e466583a81e838e79f14.jpg?s=120&d=mm&r=g)
Am 13.12.2011 17:22, schrieb Joerg Thuemmler:
Am 13.12.2011 13:43, schrieb David Haller:
Hallo,
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
Am 13.12.2011 09:56, schrieb David Haller:
Am Tue, 13 Dec 2011, Joerg Thuemmler schrieb:
mit ls -i kriegst Du die Inodes der Dateien, bei Hardlinks haben Ziel und Link die gleiche Inode-Nr. Daraus solltest Du was machen können...
Wenn man schon _die_ große Keule rausholt ist evtl. perl die besser geeignete. ... Da das ganze wohl wosiwo durch I/O gebremst wird spielt's auch keine Rolle perl zu verwenden. Im Gegenteil, einmal perl ist schneller als x-fach die Ausgabe von ls -i (rekursiv) zu verarbeiten.
nix gegen perl, das ich viel zu wenig kann und schon gar nicht gegen David ;-), aber ich sehe eigentlich keine Notwendigkeit zu rekursiven ls.
Es geht um ein Backup mit rsync/rsnapshot o.ä. ... Das wird sicher nicht nur eine Verzeichnisebene haben ...
Mein Ansatz wäre, zwei Dateien mit ls -i zu erzeugen und die dann zu vergleichen, mit ein bißchen sort [-u] und grep sollte da was zu machen sein.
Rekursiv? Ein Alptraum.
Sicher muss man die diversen Optionen für die Gestaltung des Outputs von ls auch mal ansehen, ls ist ja berühmt für die Zahl seiner Optionen ;-)
Nö. ls nich.
Das geht sicher schneller, als perl zu lernen (auch, wenn David sagen wird, dass man ohne perl eigentlich gar nicht richtig linuxen kann ;-) und es ist auch eine nette bash-Fingerübung.
Ja, es ginge in bash. Aber es wird so komplex, daß es idiotisch scheint. Rekursiv find/ls -i, sort, comm tralala ... Das ist keine Fingerübung mehr, das ist purer Masochismus. Widerleg mich, wenn du dich traust. Nur zu. Will ich sehen! Nur ein Ansatz wie meine Perl Variante reichte mir für's erste sogar!
Du bist dran, -dnh
OK, jetzt hab ich ein bißchen Zeit:
find <dir1> -ls >l1 find <dir2> -ls >>l1 sort -u -k1,1 >l2 in l2 stehen alle Dateien, die keine gleichen Inodes haben, also keine hardlinks sind, das kann ich jetzt nach dem gewünschten <dir>, von dem ich das wissen will, greppen. Da sort -u immer die 2. Zeile löscht, ist es natürlich logisch, dass <dir1> das Verzeichnis ist, wo ich die Namen wissen möchte... grep "<dir1>" <l2
sollte es tun. So im groben mal...
cu jth
kleine Korrektur, muss natürlich sort -u -k1,1 <l1 >l2 heißen, aber das ging wohl aus dem Kontext hervor... cu jth -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
![](https://seccdn.libravatar.org/avatar/c5e18be11abc2006b51660179adb46eb.jpg?s=120&d=mm&r=g)
On 2011-12-13 17:22, Joerg Thuemmler wrote:
OK, jetzt hab ich ein bißchen Zeit:
find <dir1> -ls >l1 find <dir2> -ls >>l1 sort -u -k1,1 >l2 in l2 stehen alle Dateien, die keine gleichen Inodes haben, also keine hardlinks sind, das kann ich jetzt nach dem gewünschten <dir>, von dem ich das wissen will, greppen. Da sort -u immer die 2. Zeile löscht, ist es natürlich logisch, dass <dir1> das Verzeichnis ist, wo ich die Namen wissen möchte... grep "<dir1>" <l2 Hi Joerg
Jetzt hatte ich endlich Zeit, mich dem mal näher zu widmen. Aus sort -u wurde ich nicht ganz schlau, weil es in meinen tests eben jeweils die erste datei löschte, was es für mich schwierig machte, wenn ich nicht exakt steuern kann, welche es jetzt entfernt... Ich habe mir nun mit folgendem Einzeiler geholfen: find "${PREV}" "${TARGET}" -type f -size +10M -exec ls -ish {} \+ | sort -k1,1 -n | uniq -w 8 -u | grep "${TARGET}" * PREV enthält das vorherige Verzeichnis (in deinem Beispiel dir1), TARGET das darauffolgende (dir2): Erklärung: Mich interessieren hier sowieso nur Dateien >10M und "find -ls" war mir zu verbös, daher die etwas umständlichere -exec Direktive Der 'sort' Befehl sortiert nach dem ersten Feld (den inodes) und zwar numerisch (da die inode auch kurze Nummern enthalten kann, die dann inkorrekt sortiert würden - dies ist aber nur ein kosmetisches Problem, da mich die Sortierreihenfolge nach den inodes eigentlich sowieso nicht interessiert Der darauffolgende "uniq" macht das eigentlich für mich interessante: Es entfernt alle DOPPELTEN Einträge, wobei nur die ersten 8 Zeichen (die inode) im Vergleich berücksichtigt werden. Dies lässt mich mit allen Dateien, die es nur in dem einen oder anderen Backup gibt, jetzt muss ich nur noch nach den Einträgen filtern, die mich interessieren (grep) Vielen Dank für eure Inputs! Matti -- Um die Liste abzubestellen, schicken Sie eine Mail an: opensuse-de+unsubscribe@opensuse.org Um den Listen Administrator zu erreichen, schicken Sie eine Mail an: opensuse-de+owner@opensuse.org
participants (5)
-
David Haller
-
Joerg Thuemmler
-
Lentes, Bernd
-
Matthias Keller
-
thomas Buehlmann