Roland_Linux
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Guten Morgen, ich habe mir ein kleines Skript geschrieben, das über rsync meine Daten sichert und anschließend alle Dateien, die länger als 14 Tage im Papierkorb liegen, löschen soll:
find ~/.local/share/Trash/* -mtime +14 -exec rm -r {} \;
Das funktioniert aber nur bedingt. Es bleiben immer Dateien liegen, die aber nach dem angezeigten Löschdatum gelöscht werden müssten. Bei anderen Dateien aus dem Papierkorb funktioniert es aber. Zuerst hatte ich den Parameter mtime im Verdacht, da dieser ja nur Dateien findet, deren Inhalt länger als n Tage nicht mehr geändert wurde. Daraufhin hatte ich atime probiert (Dateien, auf die länger als n Tage nicht mehr zugegriffen wurde). Beides hat aber nicht zum Erfolg geführt. Das Problem tritt bei Dateien auf, die ich lokal auf dem Rechner in den Papierkorb verschoben habe, aber auch bei Dateien, die ich über einen anderen Rechner (greift auf den freigegebenen Ordner, in dem die Datei lag, zu) gelöscht habe. An was könnte der Fehler liegen? Gibt es Alternativen zu "find ... m/atime"? Hat jemand Erfahrungen mit autotrash? Funktioniert das Skript gut? Löscht das Skript nur Dateien im Papierkorb des lokalen Systems, oder auch wenn auf einer Freigabe auf einem Server im Ordner .trash oder .Papierkorb potentielle Löschkandidaten liegen?
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
Zunächst mal hat find kein Kriterium, das den Zeitpunkt der Löschung ermitteln kann (weder -mtime noch -atime beziehen sich auf den Löschzeitpunkt). Genau genommen geht das generell nicht über die Dateieigenschaften, sondern man muss Meta-Daten des Papierkorbs zu Rate ziehen. Ich hatte mal angefangen, mir so ein Skript für Xubuntu zu schreiben. Dort muss man auf jeden Fall diese Meta-Daten auslesen und auch wieder konsistent zurück schreiben, damit alles passt. Setz mal dieses Kommando ab, dann siehst Du, was in Deinem Papierkorb so alles lungert: | find .local/share/Trash/ -ls
|
Bei mir liegen da Dateien, die auf .trashinfo enden und so aussehen: [Trash Info]
Path=/home/user/Desktop/Dateiname.pdf
DeletionDate=2017-10-13T07:52:57
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Abgesehen davon kennt das Gnu-Find -delete; die Quelle, aus der Du das mit dem -exec rm ... hast ist entweder hoffnungslos veraltet oder für andere unixoide Systeme geschrieben.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12822
|
user_unknown schrieb: Abgesehen davon kennt das Gnu-Find -delete; die Quelle, aus der Du das mit dem -exec rm ... hast ist entweder hoffnungslos veraltet oder für andere unixoide Systeme geschrieben.
Wenn wir schon bei der Kommandozeile aus dem ersten Beitrag sind, sollte man auch noch erwägen, dass ein Kriterium für Typ "Datei" fehlt. Sonst werden ggf. auch Ordner abgeräumt, die nicht verschwinden sollen.
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Vielen Dank für eure Antworten und Hilfestellung. Ich bin jetzt aber etwas überfordert. Dass meine Lösung mittels find und m-/atime nicht günstig ist, habe ich kapiert. Aber sonst stehe ich etwas auf dem Schlauch bzw. verstehe nur Bahnhof. Wie könnte sollte die Befehlszeile für mein Skript lauten, dass die Dateien zuverlässig gelöscht werden bzw. mit welchen Befehlen sollte ich besser arbeiten?
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Wäre Dein Ansatz sinnvoll, dann würdest Du
| find ~/.local/share/Trash/* -mtime +14 -delete
|
benutzen. Das Datum der Vermüllung ist zwar nicht das modification-date, da die Datei nur verschoben, aber nicht geändert wurde, aber das Datum der info-Datei stimmt mit dem Löschungsdatum, dass darin verzeichnet ist, überein (grobe Kontrolle meinerseits). Wir können also mit find die info-Dateien suchen, die älter als 14 Tage sind:
| dir=~/.local/share/Trash
find $dir/info -mtime +14 -name "*.trashinfo" -exec bash ./wegdamit.sh {} ";"
|
und einem geheimnisvollen Bashscript wegdamit.sh anvertrauen. Dieses platzieren wir besser an einem fixen Ort, und rufen es dann mit absolutem Pfad auf.
So könnte es aussehen:
| #!/bin/bash
# dir=~/.local/share/Trash
# find $dir/info -mtime +14 -name "*.trashinfo" -exec bash -c ./wegdamit.sh {} ";"
#
b=$(basename "$1" .trashinfo)
dir=$HOME/.local/share/Trash
ls -l "$dir/files/$b"
#
# rm "$dir/files/$b && rm "$dir/info/$b.trashinfo
#
|
Dieses würde also die Erweiterung .trashinfo abschneiden, die Datei im Verzeichnis files suchen, und nix machen, außer zur Kontrolle einzuladen.
Bei Kontrollzufriedenheit könnte man dann die Datei und den Kompagnonfile in info löschen:
| rm "$dir/files/$b && rm "$dir/info/$b.trashinfo
|
Den Findbefehl könnte man auch als script speichern, sagen wir als muellabfuhr.sh, und diesen mit cron alle 2 Wochen ausführen.
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Vielen Dank für deine Hilfe. Die Vorgehensweise klingt logisch und ist einleuchtend. Nur funktioniert das Abschneiden der Dateiendung .trashinfo nicht:
b=$(basename "$1" .trashinfo)
find ~/.local/share/Trash/info/$b -mtime +14 Den Fehler konnte ich bis jetzt leider noch nicht finden. Ich vermute, dass entweder das Erzeugen des Parameters oder das Einbinden des Paramters b nicht funktioniert.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Das steht ja auch nicht da. Wahrscheinlich schlecht erklärt. Also erneuter Versuch: (Nichtdestotrotz ist mir eine Verbesserung aufgefallen) Dies sei das Script wegdamit.sh. Die zwei aukommentierten Codezeilen oben dienen nur der Dokumentation, wie man es nutzen kann/soll.
| #!/bin/bash
# dir=~/.local/share/Trash
# find $dir/info -mtime +14 -name "*.trashinfo" -exec ./wegdamit.sh {} ";"
#
b=$(basename "$1" .trashinfo)
dir=$HOME/.local/share/Trash
ls -l "$dir/files/$b"
#
# rm "$dir/files/$b && rm "$dir/info/$b.trashinfo
#
|
Die auskommentierte Zeile unten dagegen soll die ls- Zeile zwei drüber ersetzen, wenn man sich vergewissert hat, dass es sauber funktioniert. Das Script ruft man so auf: | dir=~/.local/share/Trash
find $dir/info -mtime +14 -name "*.trashinfo" -exec ./wegdamit.sh {} ";"
|
sofern man in dem Verzeichnis ist, in dem wegdamit.sh liegt. Das macht den Aufruf kurz, aber wenn man es speichert wird man eher einen absoluten Pfad für wegdamit wählen. Es sucht mit find in Trash/info nach .trashinfo files, und ruft wegdamit.sh mit diesen auf. Wegdamit nimmt den Basename, also ohne Verzeichnisnamen und ohne Erweitrung .trashinfo, und schaut in Trash/files, ob die Datei existiert, bzw. führt einfach ein ls für diesen Dateinamen aus. Das sollte also alle Dateien listen, die länger als 14 Tage da rumliegen. Zum Testen vielleicht statt +14 -2 verwenden, damit die Liste nicht so groß wird, oder +360 . Wenn Meldungen kommen, dass eine Datei nicht gefunden wurde, dann ist der Müll inkonsistent.
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Vielen Dank für deine ausführliche Hilfe. Ich habe mir nun folgendes Skript gebastelt:
# Dateien aus Papierkorb löschen
echo "Die nachfolgenden Dateien liegen länger als 14 Tage im Papierkorb."
echo " "
dir=~/.local/share/Trash
a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename $dir/info/$f .trashinfo;done' sh {} +)
echo "$a"
echo " "
echo "Bitte beliebige Taste drücken, um diese endgültig zu löschen."
read pause
for f in $a
do
rm $dir/files/$f
rm $dir/info/$f.trashinfo
done
echo " "
echo "Beliebige Taste zum Beenden drücken."
read pause
Ich habe das ganze in ein Skript gepackt, so dass ich nicht mehrere Skripte verstreut auf dem Rechner liegen habe. Gerade habe ich es versucht und es funktioniert tadellos.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Das ist Glück und Zufall oder guter Geschmack und Disziplin. ☺ Nach dieser Operation:
| a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename $dir/info/$f .trashinfo;done' sh {} +)
|
Sind Dateinamen mit Leerstellen im Namen zerschnitten und führen zu Fehlern. Wozu ist denn das abschließende 'sh' da? Das funktioniert? dies: | # rm "$dir/files/$b && rm "$dir/info/$b.trashinfo
|
hätte natürlich | # rm "$dir/files/$b" && rm "$dir/info/$b.trashinfo"
|
lauten sollen und hatte den Sinn, die Trashinfo-Datei nur zu löschen, wenn auch die files-Datei gelöscht werden konnte.
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Guten Morgen, vielen Dank für deine Anregungen. Sie helfen mir doch sehr weiter, da ich das Programmieren zwar mal ein Semester im Studium hatte (for-Schleife, if-Anweisung, Variablen, usw. sind keine Fremdwörter), aber ich will mal nicht von mir behaupten, dass ich programmieren kann. Darum probiere ich einfach viel aus und hoffe dabei, dass es funktioniert. Aber wenn du Lust hast, dann lass uns doch noch etwas "basteln". Ich habe jetzt mal das sh entfernt und die rm-Anweisung so wie bei dir abgeändert:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | echo "Die nachfolgenden Dateien liegen länger als 14 Tage im Papierkorb."
echo " "
dir=~/.local/share/Trash
a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename $dir/info/$f .trashinfo;done' {} +)
echo " "
echo "Bitte beliebige Taste drücken, um diese endgültig zu löschen."
read pause
for f in $a
do
rm "$dir/files/$f && rm $dir/info/$f.trashinfo"
done
echo " "
|
Funktioniert. Ein Problem ist mir noch aufgefallen. Ich habe Laufwerke auf Servern auf meinem Rechner eingebunden. Wenn ich dort was lösche, wird auf dem Laufwerk selbst ein Papierkorb (entweder .papierkorb oder .trash-1000) erzeugt und die gelöschten Files dort gespeichert. Wie kann ich es lösen, dass auch dort die Dateien, die länger als 14 Tage gelöscht sind, gelöscht werden? Einfach das Skript mit anderer Pfadangabe wiederholen? Dann habe ich noch eine andere Situation. Ich habe auch auf meinem Rechner Freigaben erstellt, auf die ich von einem anderen Rechner darauf zugreife. Lösche ich nun vom anderen Rechner aus Dateien in der Freigabe, landet das File zwar im Papierkorb, es wird aber keine trashinfo-Datei erzeugt. Hier werden die entsprechenden Dateien dann auch nicht gelöscht. Was könnten wir hier für ein Lösungsansatz basteln? Bearbeitet von rklm: Syntaxhighlighting. Bitte nutze die Möglichkeiten des Forums!
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Roland_Linux schrieb: Aber wenn du Lust hast, dann lass uns doch noch etwas "basteln".
Du könntest sagen, ob Du willentlich auf die Behandlung von Dateien mit Leerzeichen im Pfad nicht eingehst, damit ich das weiß, und nicht rätseln muss, ob Du es übersehen oder vergessen hast, oder in Kauf nimmst.
Ich habe jetzt mal das sh entfernt und die rm-Anweisung so wie bei dir abgeändert:
echo "Die nachfolgenden Dateien liegen länger als 14 Tage im Papierkorb."
echo " "
dir=~/.local/share/Trash
a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename $dir/info/$f .trashinfo;done' {} +)
echo " "
echo "Bitte beliebige Taste drücken, um diese endgültig zu löschen."
read pause
for f in $a
do
rm "$dir/files/$f && rm $dir/info/$f.trashinfo"
done
echo " "
Funktioniert. Ein Problem ist mir noch aufgefallen. Ich habe Laufwerke auf Servern auf meinem Rechner eingebunden.
Ich nicht. Ohne sowas vor mir zu haben, um zu testen und selbst zu sehen ist mir Dateilöschen zu heikel. Aber mit dem ls statt remove sollte das ja testbar sein.
Dann habe ich noch eine andere Situation. Ich habe auch auf meinem Rechner Freigaben erstellt,
Habe ich auch nicht. Sind dann trashinfo - Dateien auf den Rechnern, von denen aus gelöscht wurde? Wie sind die Zeitstempel der Dateien?
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
OK. Dann lassen wir die Geschichte mit den Freigaben und Servern aus. Wenn die trashinfo-Dateien auf dem entfernten Rechner liegen, geht es ja genauso wie in unserem Skript beschrieben, nur das ein Ordner auf einem Server liegt. Das bekomme ich dann hin. Ich muss aber vorher überprüfen, ob und wo die trashinfo-Dateien liegen. Die Behandlung von Dateien mit Leerzeichen habe ich übersehen. Muss ich dazu im find-Befehl die Pfadangaben in Gänsefüßchen setzen?
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | echo "Die nachfolgenden Dateien liegen länger als 14 Tage im Papierkorb."
echo " "
dir=~/.local/share/Trash
a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename "$dir/info/$f" .trashinfo;done' {} +)
echo " "
echo "Bitte beliebige Taste drücken, um diese endgültig zu löschen."
read pause
for f in $a
do
rm "$dir/files/$f" && rm "$dir/info/$f.trashinfo"
done
echo " "
|
Bearbeitet von rklm: Syntaxhighlighting. Bitte nutze die Möglichkeiten des Forums!
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17552
Wohnort: Berlin
|
Roland_Linux schrieb: Die Behandlung von Dateien mit Leerzeichen habe ich übersehen. Muss ich dazu im find-Befehl die Pfadangaben in Gänsefüßchen setzen?
Tja - die Frage ist erstmal, wieso Du unbedingt im find-Befehl mit for über die Dateien iterieren willst? Zum Testen ist das äußerst unpraktisch und zum drüber räsonieren auch. Außerdem hat man in find schon genug mit eigenen Maskierungsarbeiten zu tun, da will man sich nicht unnötig mit Quotes in Quotes in SingleQuotes in Doublequotes rumärgern - das ist fehlerträchtig.
| echo "Die nachfolgenden Dateien liegen länger als 14 Tage im Papierkorb."
dir=~/.local/share/Trash
a=$(find $dir/info -mtime +14 -exec sh -c 'for f do basename "$dir/info/$f" .trashinfo;done' {} +)
|
Außerdem kannst Du das Script bei Bedarf leichter um weitere Tests erweitern, etwa erst prüfen, ob beide Dateien da sind. Deinen String a kannst Du auch mit | a=$(find $dir/info -mtime +14 -exec basename {} .trashinfo ";")
|
füllen oder ein Array
| a=($(find $dir/info -type f -exec basename -as .trashinfo -z {} ";"))
|
Die Leerstellen werden beim iterieren mit for trotzdem weg sein. Erzeug eine Datei mit Leerzeichen, wirf sie auf den Müll, und probiere es mit -mtime -1 aus. Wahrscheinlich kann man da mit IFS rumtricksen - damit kenne ich mich aber nicht aus, oder mit xargs, auch damit nicht.
|
Roland_Linux
(Themenstarter)
Anmeldungsdatum: 6. Februar 2006
Beiträge: 2396
|
Die for-Schleife habe ich eingefügt, da in meinem Suchergebnis immer nur die erste Datei ohne Pfad und Suffix .trashinfo angezeigt wurde. Alle anderen Dateien wurden mit Pfad und Suffix angezeigt. Mit der for-Schleife habe ich bezweckt, dass alle Dateien ohne Pfad und Suffix ausgegeben wurden. Ich überprüfe das aber nochmals.
|