Hallo, folgender Sachverhalt: Ein Firmen-Datei-Server muss mal grundsätzlich aufgeräumt werden, das Chaos nimmt überhand. Cheffe will die Notbremse ziehen und zukünftig auch mehr darauf achten, dass Ordnung in der Ordnerstruktur gehalten wird. Es gibt Teilbereiche, in denen eigentlich perfekte Ordnung herrscht und andere (insbesondere Entwicklungsabteilung), wo bald die Übersicht verloren geht. Schritt 1 war das Schaffen einer neuen Ordnerstruktur auf einem anderen Netzlaufwerk und das Setzen des bisherigen Fileservers auf Read-Only. Schritt 2 soll das Beseitigen von mehrfach vorhandenen Dateien auf dem alten Server sein. Sprich Dateien mit gleichem Inhalt, die mehrfach unter verschiedenen Namen in verschiedenen Verzeichnissen vorhanden sind. Es sollen alle Instanzen außer einer (beliebigen) gelöscht werden, wobei die gelöschten Dateien durch einen Symlink auf eben die eine nicht gelöschte Datei ersetzt werden sollen. Beim Kopieren auf den neuen Server bleiben dann lauter ins Leere zeigende Symlinks übrig, die anschließend gelöscht werden können. Bisher haben wir mittels "fdupes" schon eine Textdatei mit den Namen der mehrfach vorhandenen Dateien erzeugt. Diese Textdatei ist übrigens 800 MB groß, also kann man schonmal ganz gut das Problem erkennen. Die Datei hat das folgende Format: /srv/files/Benutzer/Stromberg_Bernd/Zeuch/Langweilig/letzte_Version.sch /srv/files/Entwicklung/Projekte/PS-1200/CAD/Platinen/717-8210-001.sch /srv/files/Entwicklung/Projekte/PS-1200/CAD/Platinen/717-8210-001.sch.ba k /srv/files/Produkte/PS-1200/Unterlagen/ServiceManual/717-7210-001.sch /srv/files/Benutzer/Steinke_Ulf/KantinenspeiseplanKW41.pdf /srv/files/Benutzer/Heisterkamp_Berthold/KantinenspeiseplanKW41.pdf /srv/files/Benutzer/Bursted_Erika/Leckerlecker!.pdf /srv/files/Mitarbeiter+Soziales+Betriebsrat/KantinenspeiseplanKW41.pdf Sprich, es gibt eine Auflistung aller gleichen Dateien mit jeweils einer Leerzeile dazwischen. Was ich nun bräuchte, wäre ein Bash-Skript, welches das Löschen und Verlinken übernimmt. Hier komme ich nicht weiter. Ich kann mittels einer Schleife und "read" zwar die Zeilen in eine Variable einlesen, aber ich bekomme die große Schleife außenrum, quasi die "Pro-Datei-Schleife" nicht hin. Danke für eure Hilfe!
Gerhard schrieb: > folgender Sachverhalt: Ein Firmen-Datei-Server muss mal grundsätzlich > aufgeräumt werden, das Chaos nimmt überhand. Stellt jemanden ein, der sich damit auskennt.
Sowas ist in Perl einfach machbar und sollte in Bash auch funktionieren: o Sobald eine Leerzeile kommt, Zeilen in ein Array einlesen, bis zur naechsten Leerzeile. o Schleife ueber Array: -Erstes Element im Array ignorieren -Alle nachfolgenden Elemente: Datei loeschen und Softlink mit gleichen Namen der geloeschten Datei zu erstem Element erstellen o Array loeschen o Naechstes Array bis zum Leerzeichen oder EOF einlesen
Das kannst du nicht komplett automatisieren, da ein Skript nur beschränkt entscheiden kann, welche von x identischen Dateien die eine sein soll, die aufgehoben werden soll. Du darfst dich dann mit solchen Entscheidungen rumschlagen wie "alle .bak Dateien löschen, es sei denn es gibt eine Datei nur als .bak Dateien, ausgenommen wenn das Müll ist den niemand mehr braucht". Oder soll der Speiseplan unter Kantine oder unter Soziales stehen bleiben? Und was soll das Rumgemache in den Verzeichnissen der Benutzer? Ist das wirklich so ein Verbrechen, wenn sich Benutzer eine eigene Kopie des Kantinenspeiseplans anlegen? Richte deinem Chef aus, diese Löschaktion kostet ihn mehr an Zeitaufwand und ist risikoreicher als der Kauf von ein paar weiteren Platten und Backup-Systemen. Und das er mal ein paar Regeln einführen soll, dass nur Projektdateien die im Projekt gespeichert sind, "gelten". Was Benutzer in ihrem Benutzerverzeichnis rumliegen haben sind "Experimente", die nicht "gelten" und von denen keine Veröffentlichungen (Neudeutsch Releases) gemacht werden dürfen. Das pisst dann die einsamen Helden an, aber was soll's? Dazu wäre dann mal ein Versionsverwaltungssystem fällig (noch mehr Plattenplatz und Backups).
Es geht hier um einen "Neuanfang", um ein untragbares Chaos zu beseitigen. Jeder Benutzer kann sich vom alten Server in sein neues Benutzerverzeichnis rüberkopieren, was immer er will. Und das entscheidet er auch alleine und Speisepläne sind nicht ausgeschlossen. Wie du sagtest, Benutzerverzeichnisse werden ab sofort als irrelevant, "tmp" o.ä. betrachtet und "zählen nicht". Unser DMS verwaltet Verweise auf Dokumente und speichert dazu einen Hash. Sprich alles, was irgendwie relevant für den Laden ist ("gemanagte Dokumente"), wird ohnehin automatisch durch das DMS vom alten Server in die neue Ordnerstruktur kopiert. Interessanterweise liegt ein gewisser Anteil solcher wichtigen Dokumente in irgendwelchen Benutzerverzeichnissen. Das soll halt abgestellt werden. Das Skript darf beim Löschen der redundanten Dateien tatsächlich eine ganz beliebige Kopie behalten, auch wenn die auf .bak endet und das Original gelöscht wird. Durch die Symlinks wird es ja weiterhin ansprechbar sein. Der alte Server ist - abgesehen von dieser Aktion - weiterhin read-only. Ziel ist, nach der DMS-Verschiebeaktion mal zu schauen, was übrig bleibt. Wir wollen dann entscheiden, was ins DMS aufgenommen werden sollte und was gelöscht (oder wegarchiviert) werden kann.
Macht
1 | fdupes -l sym -r /srv |
nicht genau das was du möchtest?
Mir ist noch keine fdupes-Version untergekommen, die die Kommandozeilenoption -l kennt. Verwechselst du da etwas?
Gerhard schrieb: > Das Skript darf beim Löschen der redundanten Dateien tatsächlich eine > ganz beliebige Kopie behalten, auch wenn die auf .bak endet und das > Original gelöscht wird. Durch die Symlinks wird es ja weiterhin > ansprechbar sein. Mal ein Beispiel - Du hast folgende Unterverzeichnisse: Anwendung_V200_Release Anwendung_V201_Release Anwendung_V220_Release Anwendung_V230_Release_Candidate Anwendung_V240_SysTest Anwendung_V250_Entwicklung Anwendung_V300_Test_Maier usw. In all diesen gibt es z.B. eine irgendwas.cpp oder irgendeine.pdf Nach deiner Philosophie würde dein Script alle davon bis auf eine löschen und in den anderen Verzeichnissen SymLinks anlegen. Nur was ist jetzt wenn der Kollege Maier in seiner "Spielwiese" die irgendwas.cpp verändert? Du hast Automatisch eine Änderung in allen anderen Verzeichnissen durchgeführt die dort aber überhaupt nicht gemacht werden dürfte! Bloß weil es von einer Datei mehrere Kopien auf einem Rechner vorhanden sind heißt das noch lange nicht das die nach einer Veränderung auch weiterhin gleich bleiben sollen. Viel Spas dabei jedesmal dran zu denken vor einer Änderung die Links entsprechend aufzulösen.
Wie gesagt, Neuanfang. Diese alten Verzeichnisse werden alle Read-Only sein und niemand wird mehr in seinem Testverzeichnis etwas verändern. Das Entfernen von mehrfach vorhandenen identischen Dateien auf dem Dateiserver dient lediglich zur Erleichterung des Aufräumens. Die Anzahl der zu betrachtenden Dateien wird dadurch sehr deutlich reduziert. Unsere Quelltexte liegen sowieso nicht im Verzeichnisbaum sondern haben ein separates CVS, Build- und Testsystem.
kenne das problem: gib entwicklern platz und sie scheißen ihm zu. warum muss das mit den links sein? ich würde vorschlagen du lässt den originalserver wie er ist, kopierst alle daten zum neuen server, und löschst dort mit
1 | fdupes -fdN /ordner |
alle dubletten bis auf die erste weg. ein anderer weg wäre im ziel ein dateisystem mit integrierter deduplizierung zu nutzen, hab ich aber keine erfahrung mit und kann nichts empfehlen - außerdem löst sowas nicht den overhead beim (full)backup.
da, schau mal ob dir das hilft. musst die inneren prints durch "system()" ersetzen und vorher prüfen wie dateinamen mit sonderzeichen (äöü/leerzeichen) behandelt werden.
1 | #!/usr/bin/perl
|
2 | use strict; |
3 | |
4 | my $fdupes_infile='/home/asd/out.txt'; |
5 | my @dups=(); |
6 | |
7 | open FILE, '<'.$fdupes_infile or die $!; |
8 | while (my $line = <FILE>) { |
9 | chomp $line; |
10 | if ($line =~ /^$/ ) { |
11 | my $arrlen = @dups; |
12 | print "Originaldatei: @dups[0]\n"; |
13 | for (my $numline = 1; $numline <$arrlen; $numline++) { |
14 | my $dupfile = @dups[$numline]; |
15 | print "rm $dupfile\n"; |
16 | print "ln -s @dups[0] $dupfile\n"; |
17 | }
|
18 | @dups=(); |
19 | }
|
20 | else { |
21 | push(@dups,$line); |
22 | }
|
23 | }
|
Gerhard schrieb: > Mir ist noch keine fdupes-Version untergekommen, die die > Kommandozeilenoption -l kennt. Verwechselst du da etwas? Ich verwende diese Version: https://github.com/jobermayr/fdupes/tree/opensuse
man könnte auch ganz anders rangehen. Man benennt jede Datei nach ihrem SHA1 hash um. Diese legt man ein eine einfache Verzeichnisstruktur (3 oder 4 ebenen). Jetzt kann man jeder Datei die man haben möchte, einfach den SHA1 berechnen und dann prüfen ob es schon die "hash" Datei gibt, wenn nicht anlegen sonst einfach den links setzen. Damit würde das Anwender-Verzeichnis nur aus links bestehen. Aber ich sehen noch ein anderes Problem, was ist wenn 2 Dateien gleich sind und eine Davon später geändert wird? Wie soll der Computer entscheiden ob beide Dateien sich ändern dürfen?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.