Idefix111
Anmeldungsdatum: 2. Oktober 2013
Beiträge: 71
|
Hallo, Wenn ich in der falschen Sektion bin bitte verschieben. Danke. Ich möchte in einem Netzwerk einen Server einrichten, auf dem Dateien nach einer bestimmten zeit gelöscht werden sollen. Dafür bin ich mit einem Kollegen an einem Python- Skript ausarbeiten. Das Skript funktioniert soweit eigentlich ganz gut. Ein zigstes Problem ist gerade eigentlich nur, das manchmal Ordner einfach nicht gelöscht werden und das Skript dann versucht, den Unterordner zu löschen, obwohl ja noch ein Ordner darin existiert. Das Skript wirft dann immer eine Fehlermeldung. Wir wären für jede Hilfe dankbar 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
path = ["/media/med1", "/media/med2", "/media/med3"]
now = time.time()
month = 0 #3600*24*30
def check_delete_dir(dir_path):
dir_time = os.stat(dir_path)
if((now - dir_time.st_mtime) > month):
print("delete dir: " + dir_path)
os.rmdir(dir_path)
def check_delete_file(file_path):
file_time = os.stat(file_path)
if((now - file_time.st_mtime) > month):
print("delete file: " + file_path)
os.remove(file_path)
def get_files(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
subDirPath = os.path.join(root, name)
if((now - os.path.getctime(subDirPath)) > month):
yield subDirPath
def get_folders(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in dirs:
subDirPath = os.path.join(root, name)
if((now - os.path.getctime(subDirPath)) > month):
yield subDirPath
for elem in path:
for ele in os.listdir(elem):
path_to_traverse = elem + "/" + ele
for el in os.listdir(path_to_traverse):
path_to_traverse_1 = path_to_traverse + "/" + el
list_of_files = get_files(path_to_traverse_1)
for e in list_of_files:
os.remove(e)
list_of_folders = get_folders(path_to_traverse_1)
for e in list_of_folders:
try:
os.rmdir(e)
except OSError as ex:
print(ex)
|
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
Für rekursives Löschen gibt es in der Bibliothek shutil die Funktion rmtree.
|
Idefix111
(Themenstarter)
Anmeldungsdatum: 2. Oktober 2013
Beiträge: 71
|
rmtree wäre nicht die lösung, weil nur dateien gelöscht werden sollen, die älter sind als z.b. 30 tage. rmtree löscht, glaub ich, meines wissens nach, alles in dem ordner
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
Idefix111 schrieb: rmtree wäre nicht die lösung, weil nur dateien gelöscht werden sollen, die älter sind als z.b. 30 tage. rmtree löscht, glaub ich, meines wissens nach, alles in dem ordner
Achso. Dann solltest du vor dem Löschen eines Verzeichnisses prüfen, ob noch etwas darin liegt. Ich verstehe nicht ganz den Aufbau deines Skripts. Wozu definierst du die Funktionen check_delete_file und check_delete_dir, wenn du sie nicht benutzt? Meines Erachtens würde sich für dich dafür eher eine rekursive Funktion anbieten, die sich für jeden Unterordner selbst aufruft und wieder prüft, ob dort noch Dateien jünger als 30 Tage liegen. Wenn das der Fall ist, wird die Rekursion abgebrochen. Noch ein Gedanke: Wenn du das Skript schreibst um Python zu lernen ist das eine schöne Möglichkeit. Wenn du nur effizient sein willst, geht das – wenn ich nichts übersehen habe – auch einfacher:
| # Dateien älter als 30 Tage löschen
find "/media/med1" "/media/med2" "/media/med3" -type f -ctime +30 -delete
# Leere Verzeichnisse älter als 30 Tage löschen
find "/media/med1" "/media/med2" "/media/med3" -type d -empty -ctime +30 -delete
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12795
|
Mir erscheint das ein wenig aufwändig, was Du da hast. | find /media/med{1..3} -mtime +30 -delete 2>/dev/null
|
😬 Du könntest wenigstens glob.glob() nutzen, um alle Dateien und Ordner zu finden, oder? Dann die Menge filtern und die Reihenfolge umdrehen, dann alle löschen.
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
rklm schrieb: Mir erscheint das ein wenig aufwändig, was Du da hast.
| find /media/med{1..3} -mtime +30 -delete 2>/dev/null
|
Du leitest die Fehler zwar um, sie sind aber trotzdem da, sofern ein nicht leeres Verzeichnis älter als 30 Tage existiert. Der Rückkehrcode von find wäre also dennoch 1, obwohl nicht-leere Verzeichnisse wunschgemäß übersprungen worden sind. Sofern man nachfolgende Aktionen davon abhängig machen will, wäre das also ein Problem. Wenn das nicht so ist, gehts natürlich auch so.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12795
|
misterunknown schrieb:
Du leitest die Fehler zwar um, sie sind aber trotzdem da, sofern ein nicht leeres Verzeichnis älter als 30 Tage existiert. Der Rückkehrcode von find wäre also dennoch 1, obwohl nicht-leere Verzeichnisse wunschgemäß übersprungen worden sind. Sofern man nachfolgende Aktionen davon abhängig machen will, wäre das also ein Problem. Wenn das nicht so ist, gehts natürlich auch so.
Der Rückgabewert von find ist praktisch nicht automatisch auszuwerten, weil die Manpage gar keine Aussagen dazu macht, welche Fehlerbedingungen mit welchen Problemen korrelieren. Zum Beispiel wird auch nicht unterschieden zwischen Fehlern der Kommandozeilensyntax und Fehlern bei der Ausführung. Deshalb ist es m.E. zulässig, den Rückgabewert zu ignorieren. Wenn man den Aufwand machen will, kann man es natürlich auch so machen: | tmp=$(mktemp /tmp/tmp-$(id -u)-XXXXXXX.tmp)
trap 'rm -f "$tmp"' 0
find /media/med{1..3} -mtime +30 -delete 2>"$tmp" \
|| egrep -v '^find: cannot delete ' "$tmp"
|
Dann sieht man wenigstens alle anderen Fehlermeldungen. ☺
|
misterunknown
Ehemalige
Anmeldungsdatum: 28. Oktober 2009
Beiträge: 4403
Wohnort: Sachsen
|
rklm schrieb: Der Rückgabewert von find ist praktisch nicht automatisch auszuwerten, weil die Manpage gar keine Aussagen dazu macht, welche Fehlerbedingungen mit welchen Problemen korrelieren. Zum Beispiel wird auch nicht unterschieden zwischen Fehlern der Kommandozeilensyntax und Fehlern bei der Ausführung. Deshalb ist es m.E. zulässig, den Rückgabewert zu ignorieren.
Gut, man kann sich nicht immer auf den Fehlercode verlassen, aber man kann sich auf Rückkehrcode 0 verlassen, denn dann hat alles geklappt. Ich hatte vermutet, dass gerade das der Knackpunkt beim TS ist, denn ansonsten schien sein Skript ja zu funktionieren. Ich habs aber auch nicht getestet.
Wenn man den Aufwand machen will, kann man es natürlich auch so machen:
Dann sieht man wenigstens alle anderen Fehlermeldungen.
☺
Öhm... Also... Ja, geht auch. Ohne Leer- und Steuerzeichen hat diese Lösung aber ein Zeichen mehr, als meine 2 finds:
| find"/media/med1""/media/med2""/media/med3"-typef-ctime+30-deletefind"/media/med1""/media/med2""/media/med3"-typed-empty-ctime+30-delete
tmp=$(mktemp/tmp/tmp-$(id-u)-XXXXXXX.tmp)trap'rm-f"$tmp"'0find/media/med{1..3}-mtime+30-delete2>"$tmp"||egrep-v'^find:cannotdelete'"$tmp"
|
😎 😀 scnr
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12795
|
misterunknown schrieb:
Gut, man kann sich nicht immer auf den Fehlercode verlassen, aber man kann sich auf Rückkehrcode 0 verlassen, denn dann hat alles geklappt. Ich hatte vermutet, dass gerade das der Knackpunkt beim TS ist, denn ansonsten schien sein Skript ja zu funktionieren. Ich habs aber auch nicht getestet.
Du hast offensichtlich auch nicht den Eingangsbeitrag gelesen. ☺
|
Idefix111
(Themenstarter)
Anmeldungsdatum: 2. Oktober 2013
Beiträge: 71
|
Hallo, danke für die Antworten, ich hab aber in der Zwischenzeit eine andere lösung gefunden. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
path = ["/media/med1", "/media/med2", "/media/med3"]
now = time.time()
month = 60.0 #3600*24*30
def get_files(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
subDirPath = os.path.join(root, name)
if((now - os.path.getmtime(subDirPath)) > month):
yield subDirPath
def get_folders(path):
for root, dirs, files in os.walk(path, topdown=False):
for name in dirs:
subDirPath = os.path.join(root, name)
file_creation_time = os.stat(subDirPath).st_ctime
if((now - file_creation_time) > month or (now - file_creation_time) < 1.0):
yield subDirPath
#for num in range(0,3):
for elem in path:
for ele in os.listdir(elem):
path_to_traverse = elem + "/" + ele
for el in os.listdir(path_to_traverse):
path_to_traverse_1 = path_to_traverse + "/" + el
list_of_files = get_files(path_to_traverse_1)
for e in list_of_files:
os.remove(e)
list_of_folders = get_folders(path_to_traverse_1)
for e in list_of_folders:
try:
os.rmdir(e)
except OSError as ex:
if ex.errno == os.errno.ENOTEMPTY:
pass
else:
raise
|
|