Shell Problem

S

stone89

Grünschnabel
Hallo
Ich programmiere noch nicht so lange Shell Skripte wie einige von euch.
Achso bevor ichs vergesse, ich nutze die Shell unter Suse 10.3 das ist die bash
Habe erst kürzlich in der Schule damit angefangen. Habe da bei einer Aufgabe ein Problem.
Aufgabenstellung lautet wie folgt :
Schreiben Sie ein Skript, dass alle Dateien mit der länge 0 Byte im angegeben Verzeichnis zählt, anschließend auflistet und abfragt, ob die Dateien gelöscht werden sollen. Die Anzahl der übergebenen Parameter ist zu prüfen.
Mein Ansatz hier zu schaut wie folgt aus
Code:
cd .. #in root Ordner Wechseln
echo Pfad eingeben 
read $Pfad #Lese Pfad   
cd $Pfad  #Geht zum Pfad
ls        # listing des Ordners des Pfades
echo Alle Dateien mit 0 Byte
echo ""
find -size 0 
ls
echo Möchten Sie $element[x] löschen? Y oder N
read $eingabe

Schleife drum rum aber wie :-)

if [$eingabe=Y]
then 
rmdir $element[x]
x++
elif [$eingabe=N]
then x++
else 
sh linux4.sh
fi

Nun ist die Frage, wie genau ich das dann mit der eingabe einlesen und überprüfen machen kann. Des weiteren wie das genau funktioniert, das ich die Funktion wie gefordert erhalte.

Code:
echo Pfad eingeben 
read $Pfad #Lese Pfad   
cd $Pfad  #Geht zum Pfad

An der Stelle stellt sich für mich die Frage, wie ich es hinbekomme das ich in mehrer Verzeichnise dann wechseln kann. Weil ich mach ja vorher das cd .. dann komm ich ja in den root ordner aber wenn ich von da in den Ordner Desktop und dort in den Ordner Sicherung springen will wie kann ich das realisieren?
 
Zuletzt bearbeitet:
Warum wechselst Du immer mit cd? Du kannst 'ls $PATH' benutzen genauso wie 'rm $FILE' wobei $FILE ein absoluter Filename ist. Das macht es wesentlich einfacher.
 
Und mit while und read kannst du ohne Probleme die Parameter einlesen.

Googlen nach while + read + bash dürfte dir mehr als genug brauchbare Beispiele geben.
 
Das folgende Fragment zeigt die wichtigsten Dinge.

Code:
P=$1    # path

i=0
find $P -size 0 | while read FILE; do
        element[$i]=$FILE
        let i=i+1
done

j=0
for ((j=0; j<$i; j++)); do
        echo -n "Delete ${element[$j]} ?"
        read A
        if [[ $A == "y" ]]; then
                echo "rm $element[$j]"
        fi
done
 
Hallo
Danke Framp für deine Hilfe. Hab das jetzt mal versucht umzusetzen.
Der Code sieht wie folgt aus:
Code:
cd .. #in root Ordner Wechseln
echo Pfad eingeben 
read eingabe #Lese Pfad
P=$eingabe     # path
cd $P
i=0
find $P -size 0 | while read FILE; do
        element[$i]=$FILE
        let i=i+1
done
echo weiter
j=0
for ((j=0; j<$i; j++)); do
        echo -n "Delete ${element[$j]} ?"
        read A
        if [[ $A == "y" ]]; then
                echo "rm $element[$j]"
        fi
done
echo Ende

Ich hoffe ich das so richtig verstanden, wie du das da hingeschrieben hattest. Wie gesagt mach das noch nicht so wahnsinnig lange. Hab mir auch schon einige Skripte angesehn. Beispielsweise das Tutorial auf Tutorials.de und das von Self Linux. Also hab mich schon damit beschäftigt. So die ersten Aufgaben die wir hatten konnt ich auch ganz gut lösen, nur immoment haperts.
Bei der Source die ich ein wenig angepasst habe Arbeitet er das obere ab. Sagt aber er findet keine Datei mit 0Byte obwohl ich ein paar dummys erstellt habe. Und nach der abarbeitung sollte er ja welche gefunden haben und in die for springen. Allerdings springt er dann einfach zum ende und das wars. :hilfe2:
 
Erstens:
Crossposting ist nicht erwünscht.
Zweitens:
Dein while read läuft in einer Subshell, deshalb sind die Variablen nach Verlassen wieder unbekannt, bzw leer.
Lösung:
Pack die Aktion in deine while read Schleife direkt rein.

Wolfgang
 
Sorry wegen dem Crossposting.
Kommt nicht mehr vor. versprochen.
 
Zweitens:
Dein while read läuft in einer Subshell, deshalb sind die Variablen nach Verlassen wieder unbekannt, bzw leer.
Lösung:
Pack die Aktion in deine while read Schleife direkt rein.

Eine Möglichkeit das Problem zu lösen. Wie kann man aber die Laufvariablen an die externe Subshell weiterreichen? export funktioniert leider nicht :(
 
Das liegt hier an der Pipe.
Du kannst aber das Ergebnis von find gleich in ein Array packen.
Code:
F=();
F=($(find ./ -type f ));
Ein export bringt nix, da die subshell nicht an die parent Shell exportieren kann.
Das geht nur andersrum.
Die andere Lösung habe ich oben genannt.

Gruß Wolfgang
 
<OT>Nice feature. Ich setze bislang immer perl oder awk ein wenn ich Arrays brauche. Kannst Du mir einen Hint/Link geben, was bei T=(...) eigentlich im Hintergrund abläuft? </OT>

Code:
#!/bin/bash

P=$1    # path

element=($(find $P -size 0))

j=0
while [ ${element[$j]} ]; do
        echo -n "Delete ${element[$j]} ?"
        read A
        if [[ $A == "y" ]]; then
                echo "rm $element[$j]"
        fi
        let j=j+1
done

sieht schon wesentlich eleganter aus
 
<OT>Nice feature. Ich setze bislang immer perl oder awk ein wenn ich Arrays brauche. Kannst Du mir einen Hint/Link geben, was bei T=(...) eigentlich im Hintergrund abläuft? </OT>

Vorsicht, das läuft vor die Wand, wenn Dateien mit häßlichen Leerzeichen vorkommen.
Zu Array in der bash sieh dir mal die man bash an.
Das hier
Code:
T=($(command))
gibt die Ausgabe des $(command) in ein Array.
$(command) ist die neue Schreibweise für Backtick command Backtick.
Backticks sind in der bash/ksh deprecated.

Gruß Wolfgang
 
Thx. Habe die Infos in der man Page gefunden. Werde mir wohl mal demnächst die gesamte man page mit ihren 5000 Zeilen mal durchlesen. Scheint noch mehr features in der bash zu geben die ich noch nicht kenne :))
 

Ähnliche Themen

Shell Skript beschleunigen

HandbrakeCLI Shell Skript

Skript bei Lubuntu nach jedem Start ausführen

Queue für copy Script

Shellskript - Fehler in Cron

Zurück
Oben