Löschroutine mit Überprüfung

R

relkai

Grünschnabel
Hallo Freunde der Bash,

ich habe ein inzwischen recht langes Script, welches bei manuellem Aufruf durch bestimmte Unterverzeichnisse wandert und diverse Aufgaben durchführt.

Nun beiße ich mir aber schon seit Stunden an einer in meinen Augen eigentlich recht trivialen Sache die Zähne aus:
Das Script soll unter anderem bestimmte Verzeichnisse von Unrat befreien, und vor dem Löschen eine Dateiliste der Dateien ausgeben, welche NICHT gelöscht werden (leerzeichen sollten auch berücksichtigt werden).

In stark vereinfachter Form versuche ich also folgendes Script-Schnipsel auszuführen:
Code:
#!/bin/bash

muell=" *.avi
        *.mpg
        *.mp3"

for i in ${muell}; do
        ls_ignore="${ls_ignore} --ignore='${i}'"
done

echo -e "\n\033[1;32mDiese Dateien werden nicht geloescht:\033[0m"
ls -l ${ls_ignore}

while [ "$loeschen" != 'j' -a "$loeschen" != 'n' ]; do
        echo -en "\n\033[1;34mSoll Datenmuell geloescht werden? (j/n) \033[0m"
        read -n 1 loeschen
done
if [ "$loeschen" == 'n' ]; then
        echo -e "\n\033[1;32mNichts wird geloescht\033[0m"
else
        echo -e "\n\033[1;32mLoesche Datenmuell\033[0m"
        rm -r $muell 2>/dev/null
fi

Ich moechte also jedem Eintrag aus der Variable $muell ein "--ignore=" voranstellen, und die daraus resultierende Variable $ls_ignore als Parameter dem "ls" Befehl mitgeben.

Im aktuellen Verzeichnis befinden sich bei meinen Tests folgende Dateien:
Code:
# ls -ls
insgesamt 0
0 -rw-r--r-- 1 root root 0 23. Sep 15:03 Diese Datei loeschen.avi
0 -rw-r--r-- 1 root root 0 23. Sep 15:06 Nicht loeschen.txt

Führe ich das Script aus, erhalte ich jedoch als Fehlermeldung:
Code:
ls: Zugriff auf Datei nicht möglich: Datei oder Verzeichnis nicht gefunden
ls: Zugriff auf loeschen.avi' nicht möglich: Datei oder Verzeichnis nicht gefunden

Ersetze ich den "ls" Befehl durch ein "echo ${ls_ignore}", erhalte ich folgende Ausgabe:
Code:
--ignore='Diese Datei loeschen.avi' --ignore='*.mpg' --ignore='*.mp3'

Kopiere ich diese Ausgabe manuell und füge sie direkt in der Bash als Parameter nach einem "ls -l" ein, funktioniert es tadellos:
Code:
# ls -l --ignore='Diese Datei loeschen.avi' --ignore='*.mpg' --ignore='*.mp3'
insgesamt 0
-rw-r--r-- 1 root root 0 23. Sep 15:06 Nicht loeschen.txt

Ich habe natürlich noch die Möglichkeit, eine weitere Variable manuell in meinem Script zu erstellen, also in der Art:
Code:
ls_ignore=" --ignore=*.avi
            --ignore=*.mpg
            --ignore=*.mp3"

Auch dies funktioniert tadellos, erhöht nur bei vielen Muell-Einträgen die Fehlerquote, da immer zwei Variablen gepflegt werden müssen.

Jetzt aber zu meiner Kernfrage (wird auch Zeit):
Wo liegt mein Denkfehler? Warum kann ich den Inhalt der selbst-gestrickten Variable direkt auf der Bash als Parameter verwenden, aber nicht innerhalb meines Scripts?
Gibt es einen besseren als den von mir skizzierten Weg, dies zu erreichen?

Wäre klasse, wenn mich jemand in die richtige Richtung schubsen würde, da ich kurz davor stehe, ein Stück aus meiner Tastatur herauszubeißen.

Besten Dank und Gruß,
relkai
 
Hi,

versuch mal, die Zeilen
Code:
for i in ${muell}; do
        ls_ignore="${ls_ignore} --ignore='${i}'"
done
einfach durch
Code:
ls_ignore=$(echo "$muell" | sed -e 's/[         ]*/--ignore=/')
(mit einem Blank und einem TAB innerhalb der [ ]) zu ersetzen. Solange dein "$muell" immer schön ein Muster pro Zeile definiert, müsste das eigentlich schon reichen.

Probleme macht dir zum einen wohl, dass die Shell innerhalb der for-Schleife den '*' bereits expandiert, wie du durch Einfügen von
Code:
echo "ls_ignore=<$ls_ignore>"
direkt nach der Schleife erkennen kannst. (Die '*' bleiben nur erhalten, wenn im aktuellen Verzeichnis keine Datei vorhanden ist, auf die das entsprechende Muster passt.)

Zum anderen werden danach beim "ls -l $ls_ignore" die Muster (bzw. Dateinamen) an den Leerzeichen in einzelne Argumente aufgespalten. Das heisst, der ls bekommt u.a. ein '--ignore=Diese' und ein 'Datei' vorgesetzt, und beschwert sich natürlich, dass 'Datei' nicht vorhanden ist. (Das siehst du sehr schön, wenn du vor die "ls -l"-Zeile z.B. ein "set -x" einfügst).

Gruss, A.
 
Großartig - vielen Dank, floyd62!

Dein Tipp, die Variable mit sed zu bearbeiten, ohne sie durch eine for-Schleife zu jagen (und sie somit der Bash-Completion zum Fraß vorzuwerfen), funktioniert einwandfrei.
Ich habe zuvor schon versucht, das Auflösen der Wildcards durch diverse Anführungszeichen um die Variablen zu verhinden, oder eine "while read" Schleife zu verwenden, habe mir aber jedesmal die Nase an einem Problem gestoßen.

Mein größtes Problem ist wohl, dass ich noch nicht sehr vertraut mit Regular Expressions bin - daran werde ich wohl dringend arbeiten müssen.

Also noch einmal meinen innigsten Dank!!
 
Ich möchte zwar nichts zum Thema schreiben, aber mal ein ausdrückliches Lob an relkai loswerden.
Das muss auch mal sein, wenn hier (und in anderen Foren) doch immer auf den Erstlingswerken einiger neuer User (mit guten Grund) rumgehackt wird.

Ein vorbildlicher Eingangspost.

Alle Informationen, eigene Versuche und Fehlermeldungen drin, die man braucht, um sich ein Bild zu machen und vielleicht das Problem zu lösen, was floyd62 dann ja auch fix mal gemacht hat. ;-)
 
Danke für Dein Lob! Das geht runter wie geschmolzene Butter!

Da ich als Systemadministrator arbeite, weiß ich wie anstrengend Anfragen wie "Hier funktioniert mal wieder nichts" sind. Wenn man selbst auf Nachfrage einer Konkretisierung des Problems ein "Naja, GAR NICHTS" erhält, macht es die Fehleranalyse nicht gerade einfacher.
Ich denke, so verhält es sich häufig in Foren dieser Art - viele posten nur Bruchteile ihres Problems und erwarten vom Helfenden, dass er sich trotz der mangelnden Informationen prima in das Problem hineindenken kann...schließlich hat man es ja mit Spezialisten zu tun.

Also werde ich auch zukünftig versuchen, mein Problem möglichst genau zu umschreiben und bereits versuchte Maßnahmen mitzuliefern.
Schade, dass ich dieses Forum erst jetzt entdeckt habe - bei dieser prompten und kompetenten Hilfe hätte ich mir manche Pulerei (obwohl genau DAS auch Spaß machen kann) ersparen können.
 

Ähnliche Themen

Verschlüsseltes Backup-Script mit rsync

HandbrakeCLI Shell Skript

Zugriff Ubuntu 16.04. auf Freigabe 18.04. LTS nicht möglich

[Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter

verzeichniss suche funktioniert nicht

Zurück
Oben