S: Seite für Bash Skripte

Post Reply
Message
Author
malteh
Posts: 1
Joined: 22. Aug 2004 17:17

S: Seite für Bash Skripte

#1 Post by malteh »

Hallo Forum,

kennt Ihr eine Seite wo man Bash Skripte herunterladen kann?


Viele Grüße

Malte

Malte H

#2 Post by Malte H »

Vielleicht könntet Ihr mir einen Tip geben. Ich möchte alle Verzeichnisse ohne Dateien löschen. Das folgende Script tut das schon in etwa. Es gibt aber Probleme wenn in einem Verzeichnis Leerzeichen (Sonderzeichen) vorkommen. Wie kann ich den Befehl
`find "$VERZ" -type d`
so umschreiben das es hier keinen Fehler mehr gibt.


Viele Grüße

Malte

Code: Select all

#!/bin/sh
VERZ=
ANZ=

# Es wird ein Verzeichnis als Parameter erwartet. Wenn nichts angegeben wird pwd genommen.
if [ $# -eq 1 ] ; then
  if [ -d $1 ] ; then
    VERZ=$1
  else
    echo "Parameter ist kein Verzeichnis."
    exit 1
  fi
else
  VERZ=`pwd`
fi

# Alle Verzeichnisse ohne Dateien löschen.
for file in `find "$VERZ" -type d` ; do
  ANZ=`ls -la "$file" | wc -l`  
  if [ $ANZ -eq 3 ] ; then
    echo "$file"
    #rmdir "$file"
  fi
done

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#3 Post by jochen »

Die Shell zerlegt den Output des find-Kommandos anhand der Trenner in der Variablen IFS. Deren Inhalt sollte man aber vor dem Ändern sichern und hinterher zurücksetzen.

Ausserdem - wenn schon Leerzeichen in Verzeichnisnamen auftauchen können, solltest Du bei der Prüfung des ersten Arguments "$1" statt nur $1 schreiben.

Wenn Du VERZ auf das aktuelle Verzeichnis setzen willst, kannst Du einfach "VERZ=." statt "VERZ=`pwd`" schreiben. Da steckt der Verzeichnisname zwar nicht ausgeschrieben drin, aber funktionieren tut es genauso.

Wenn Du auf die Anzahl Dateien im Verzeichnis testest (ANZ=`ls -la "$file" | wc -l`), warum verwendest Du dann die Langform (-l) bei ls? Die Infos interessieren Dich doch gar nicht. Ein "ls -a" tut's auch. Lass Dich nicht davon irritieren, dass die Ausgabe dann spaltenweise erfolgt; das passiert nur, wenn ls auf ein Terminal ausgibt. Wenn die Ausgabe so wie hier in eine Pipe erfolgt, erscheint pro Zeile eine Datei. Vorsichtshalber kannst Du ja auch noch die Option "-1" setzen, die dieses Verhalten immer erzwingt. Zu guter Letzt kannst Du dann gegen "Anzahl Dateien == 2" ("." und "..") testen und musst nicht die "total"-Zeile der ls-Langform mitrechnen. Das hatte ich zuerst für einen Fehler gehalten, weil klar war, was Du machen wolltest, die Anzahl vorhandener EInträge in einem leeren Verzeichnis aber 2 sein muss...

Und schliesslich: Wenn ich bei der Entwicklung gefährliche Kommandos wie rmdir entschärfen will, setze ich einfach nur ein echo davor. So sieht man direkt, wie das Kommando ausgeführt werden würde und nicht nur die erarbeiteten Parameter.

So sieht die Variante aus, wo ich alle o.a. Punkte eingebaut habe:

Code: Select all

#!/bin/sh
VERZ=
ANZ=

# Es wird ein Verzeichnis als Parameter erwartet. Wenn nichts angegeben wird pwd genommen.
if [ $# -eq 1 ] ; then
  if [ -d "$1" ] ; then
    VERZ="$1"
  else
    echo "Parameter ist kein Verzeichnis."
    exit 1
  fi
else
  VERZ=.
fi

# Alle Verzeichnisse ohne Dateien löschen.
OIFS="$IFS" ; IFS=""
for file in `find "$VERZ" -type d` ; do
  ANZ=`ls -a "$file" | wc -l` 
  if [ $ANZ -eq 2 ] ; then
    echo rmdir "$file"
  fi
done 
IFS="$OIFS"
Die grösste Lüge der EDV? "Mal eben..."

Malte H

#4 Post by Malte H »

Hallo Jochen,

vielen Dank für die Tips.
Jetzt kriege ich den Fehler
/bin/ls: Argument list too long
Vielleicht wäre es besser wenn ich einmal durch alle Verzeichnisse durchgehe. Einzeln...
Unter Linux gab es doch einen Befehl wo man den Pfad eines Komandos herauskriegen konnte. Wie hieß das nochmal?
Kennst Du keine Seite wo man sich Code Schnipsel der Shellprogrammierung ansehen könnte?


Viele Grüße

Malte


User avatar
Hans Solo
prolinux-forum-admin
Posts: 601
Joined: 20. Apr 2004 12:19
Location: AT
Contact:

#6 Post by Hans Solo »

hi
>> Befehl wo man den Pfad eines Komandos herauskriegen konnte
which <kommando>

mfg
arno
[root@host]# cd /pub
[root@host]# more beer

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#7 Post by jochen »

Sorry, mein Fehler: In IFS muss noch das Newline stehenbleiben, nur TAB und Space dürfen nicht drinne auftreten. Das kommt davon, wenn man etwas mit 'nem anderen Skript testet, als das, was man dann postet...

Verbesserte Fassung:

Code: Select all

#!/bin/sh
VERZ=
ANZ=

# Es wird ein Verzeichnis als Parameter erwartet. Wenn nichts angegeben wird pwd genommen.
if &#91; $# -eq 1 &#93; ; then
  if &#91; -d "$1" &#93; ; then
    VERZ="$1"
  else
    echo "Parameter ist kein Verzeichnis."
    exit 1
  fi
else
  VERZ=.
fi

# Alle Verzeichnisse ohne Dateien löschen.
OIFS="$IFS" ; IFS="
"
for file in `find "$VERZ" -type d` ; do
  ANZ=`ls -a "$file" | wc -l`
  if &#91; $ANZ -eq 2 &#93; ; then
    echo rmdir "$file"
  fi
done
IFS="$OIFS" 
Dass Dir aber die argument list platzen kann liegt daran, dass Du mittel `find...` dort den Output des find-Kommandos in die Kommandozeile einsetzen lässt. Wenn das sehr viele Verzeichnisse sind, kann der 32KiB-Buffer der Schell für solchen Zwecke schon mal zu eng sein -> argument list too long.

Probier mal das obige Skript aus und sag Bescheid, ob es das Problem jetzt gelöst hat. Sollte es immer noch krachen, schreiben wir's halt um. :)

Jochen
Die grösste Lüge der EDV? "Mal eben..."

Malte H

#8 Post by Malte H »

Vielen Dank Euch allen:-)
Das Skript funktioniert jetzt auch.

Viele Grüße

Malte

Post Reply