PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe bei Shell-Script



15-09-2000, 09:20
Hallo,
zur Erstellung eines Shellscripts bräuchte ich Eure Hilfe (ich bin Anfänger):

1. ich möchte überprüfen, ob ein bestimmtes Verzeichnis leer ist, also ob keine Dateien enthalten sind und abhängig davon etwas unternehmen. Es muß egal sein, ob sonst eine oder mehrere Dateien enthalten sind.

2. das Ganze findet in einer Schleife "for i in * do ... done " statt, wobei dann, wenn obiges Verzeichnis nicht leer ist, nach der Abarbeitung von bestimmten Befehlen, mit dem nächsten Durchlauf der For-Schleife weitergemacht werden soll, ohne das die sonstigen Befehle berücksichtigt werden. Wie kann man das machen?

3. Wenn ich in eine Script folgendes mache:
cd /verzeichnis
for i in *
do
echo "ausgeführt" >/verzeichnis2/datei
done

dann werden bei mir zwei Einträge in /verzeichnis2/datei erzeugt. Es sieht so aus, als wenn . und .. berücksichtigt werden.
Wie kann ich dies verhindern?

4. in einer anderen Prüfung soll ein Verzeichnis nach bestimmten Dateitypen geprüft werden. Dabei soll festgestellt werden, ob Dateien mit ".exe" ".dll" ".ins" usw. vorhanden sind. Wenn ja sollen bestimmte Befehle abgearbeitet werden und die obige For-Schleife erneut durchlaufen werden,
wenn nein, soll normal weitergemacht werden.

Anbei, das Script, soweit ich momentan bin (ungetestet)
##########################################
#!/bin/bash
# Shell-sript zum automatischen Entpacken von Zip-Dateien
# Wechseln ins Einlauf-Verzeichnis
cd /ska_fs2/pool/skadaten/unzip/einlauf

# Suchen nach den ZIP-Dateien

# 3)
for i in *.zip
do
# Ausgabeverzeichnis erstellen
mkdir ../ausgabe/$i
# Zipdatei auf Viren Pruefen,
# verseuchte Dateien nach /root/infected kopieren
/usr/local/uvscan/uvscan $i -m /root/infected
# Bei Virenbefall Hinweisdatei in Ausgabeverzeichnis erstellen
# Mail versenden 1 + 2)
###### cp /root/batches/unzip/v_info.txt ../ausgabe/$i/v_info.txt.$i
###### mail -s "$i" mail@mail.de</root/batches/unzip/virus.txt
# Zipdatei in Arbeitsverzeichnis entpacken
/usr/bin/unzip $i -d /root/arbeit/$i
# Inhalt des Arbeitsverzeichnisse auf Viren pruefen
# verseuchte Dateien nach /root/infected kopieren
/usr/local/uvscan/uvscan /root/arbeit/$i -m /root/infected
# Bei Virenbefall Hinweisdatei in Ausgabeverzeichnis erstellen
# Mail versenden 1 + 2)
###### cp /root/batches/unzip/v_info1.txt ../ausgabe/$i/v_info.txt.$i
###### mail -s "$i" mail@mail.de</root/batches/unzip/virus.txt
# cd /root/arbeit/$i 4)
# Dateien auf Programme testen
# Dateien mit .exe, .dll, .ins usw
# Wenn Programm nur Datei mit Programmhinweis
# nach Ausgabeverzeichnis kopieren

# Inhalt des Arbeitsverzeichnisse nach Ausgabeverzeichnis verschieben
mv /root/arbeit/$i/*.* ../ausgabe/$i/
# Arbeitsverzeichnis loeschen
rm -r /root/arbeit/$i
# Orginalzip loeschen
rm $i
done
############################################

Könnt Ihr mir helfen?
MfG,
Werner

thommy
15-09-2000, 10:47
Zu 1.

Einen direkten Text, ob ein Verzeichnis etwas enthält, ist mir nicht bekannt; Du kannst hier nur über das Ergebnis bspw. von "ls" gehen.

Zu 2.

Wenn "*" nicht expandiert (weil das Verzeichnis leer ist), wird "*" an i (in der Bash) zugewiesen. Deshalb findet immer ein Schleifendurchlauf statt.

Zu 3.

Mit .-Dateien:
<pre>
set $(ls -a)
shift 2 # die beiden ersten Argumente überspringen (. und ..)
for i do
echo $i
done
</pre>

Zu 4.

Einfach testen, ob $(ls *.exe) ... etwas liefert


Thomas

15-09-2000, 11:34
Hallo,
zu 1) ich hatte mir gedacht, dass man eine leeres Verzeichnis vielleicht mit "ls -l|wc -l" prüfen könnte. Ein leeres Verzeichnis bringt damit bei mir immer 3 als Wert.
Nur kann ich den Rückgabewert nicht in eine Variable schreiben und dann vergleichen. Weißt Du, wie das geht?
zu 2) da habe ich mich wohl nicht genau ausgedrückt:
wenn innerhalb der for-schleife nach einer if-Schleife das if true ist, sollen die dafür vorgesehenen Befehle ausgeführt werden, aber die hinter der IF-Schleife stehenden nicht mehr, sondern am Anfang der Forschleife weitergemacht werden.
Gibt es hier sowas wie break, für beenden der Forschleife, oder muß man das mit einem "goto" machen?
zu 4) ich stehe auf dem Schlauch,
wie kann ich es testen?
Danke für die Hilfe,
Werner

15-09-2000, 20:22
Hi,
ich habe weiter gemacht, anbei der bisherige Text:

#!/bin/bash
# Shell-sript zum automatischen Entpacken von Zip-Dateien
# Wechseln ins Einlauf-Verzeichnis

INDIR="/nw-dienste/pool/organisation/unzip/in/"
OUTDIR="/nw-dienste/pool/organisation/unzip/out/"
INFECT="/root/batches/unzip/infected/"
VIRUS="/root/virus/"
ROOTDIR="/root/batches/unzip/"
cd ${INDIR}

# Suchen nach den ZIP-Dateien

for i in *.zip
do
# Ausgabeverzeichnis erstellen
echo "Schleife"
mkdir ../out/$i
# Zipdatei auf Viren Pruefen,
# verseuchte Dateien nach /root/infected verschieben
# /usr/local/uvscan/uvscan $i -m /root/batches/unzip/infected
cd ${ROOTDIR}
# folgendes prueft, ob im benanten Verzeichnis Dateien
# vorhanden sind,
# wenn Dateien vorhanden sind wird die Schleife ausgefuehrt
# wc -w zaehlt die Vorkommen
ANZAHL=$(ls /root/batches/unzip/infected |wc -w)
if [ $ANZAHL -ne 0 ]
then
# Bei Virenbefall Hinweisdatei in Ausgabeverzeichnis erstellen
cp ./virushinweis ${OUTDIR}/$i/virushinweis.$i
cat ./virushinweis >>${OUTDIR}/$i/virushinweis.$i
# Dateien im Virenpruefverzeichnis loeschen
rm -r ${INFECT}*
# Orginalzip in Virusverzeichnis verschieben und loeschen
cd ${INDIR}
cp -r -f $i ${VIRUS}
rm $i
# Mail an v-kaemmerei.sys versenden
mail -s "Virus in $i gefunden " w.ginzky@domaene.de<${ROOTDIR}virus.txt
# for-schleife mit naechsten Durchlauf beginnen
zum naechsten Zip-File
fi
###### cp /root/batches/unzip/v_info.txt ../ausgabe/$i/v_info.txt.$i
###### mail -s "$i"
done # Ende for-schleife

*****
momentan habe ich erstmal zwei Probleme, wenn das Verzeichnis schon besteht, gibt es eine Fehlermeldung, außerdem läuft das Script nur einmal durch die Schleife obwohl zwei Zips vorhanden sind. Probiert habe ich "continue", "break" und "next". Die ersten beiden brechen die Schleife ab, der Letzte ist unbekannt.
Was muß ich in der IF-Schleife schreiben, um beim nächsten Zip-File weitermachen zu können, obwohl hinter der IF-Schleife noch weitere Befehle kommen, die ausgeführt werden sollen, wenn die IF-Schleiche nicht durchlaufen wird.
MfG,
Werner

15-09-2000, 20:23
Hi,
mein kopiertes Script ist schön formatiert, leider wird es nicht übernommen, sorry.
Werner

pitu
16-09-2000, 00:15
Zu 1:

test -z `ls -A` && echo "ist leer"

-A an ls laesst . und .. weg. mit deb Backticks (``) führst du ein Programm aus, und gibtst den Wert zurueck. also auch:

LS=`ls -A` bedeutet, das die Rückgabe von "ls -A" in der Variable LS abgespeichert wird.

Mit "test -z" testest du, ob "ls -A" die Länge 0 hat.

&& bedeutet, wenn wahr (test) dann mache. ...
| | wuerde bedeuten, wenn falsch.

in einer if Abfrage würde das so aussehen:

if test -z "$LS" ; then
echo ist leer
fi

zu 2)
Aus einer for-Schleife kommst du mit "break" raus.

#zu 3)
for i in `ls -A`; do

#($i wird in 4 verwendet.)

#zu 4)
#mach ein case:

case "$i" in
*zip)
tu_was
;;
*exe)
tu_auch_was
;;
*dll)
tu_was_anderes
;;
esac

#(aus 3 http://www.linuxforen.de/ubb/smile.gif
done
---------------------------------------
Script:

<pre>

#!/bin/bash
#Automatisches Entpacken und Virenprüfen

# $1 ist der File der ausgepackt werden soll.
# $2 ist ein Verzeichniss welches verwendet werden soll
# Optional, da ansonsten im gleichen Verzeichniss eins angelegt wird.

# Welches unzip, wo?
UNZIP="/usr/bin/unzip"
# Welche Option benötigt es um in ein Verzeichniss auszupacken
DIR_OPT="-d"
# Andere Optionen
ZIP_OPT=""

# Virenscanner
$INFECTED="infected"
SCANNER="/usr/local/uvscan/uvscan"
SCAN_OPT=""
SCAN_DIR="-m"

FILE="$1"
DIR="$2"
test "$2" | | DIR=`basename $FILE .zip`

# Wenn kein Verzeichniss angegeben wird, wird mit diesem
# test verhindert, das ein eventuell existierendes verzeichniss
# verwendet wird.
if [ -d "$DIR" -a -z "$2" ]; then
echo "Verzeichniss existiert schon"
echo "Bitte extra eins angeben."
exit1
fi

# Legt das Directory an
mkdir $DIR

# Packt in das Directory aus
$UNZIP $FILE $ZIP_OPT $DIR_OPT $DIR

# Überprüft in dem Verzeichniss auf Viren
test -d $HOME/$INFECTED | | mkdir $HOME/$INFECTED

for i in `ls -A $DIR`; do
$SCANNER $i $SCAN_OPT $SCAN_DIR $HOME/$INFECTED
done

</pre>
----------------------------

Das sind erstmal ein paar Gedanken, so als Einstieg. Probier mal weiter dran rum. und vor allem, vergiss das formatieren nicht, es wird lesbarer ;-)

mist, "pre" schmeisst trotzdem die leerzeilen hier raus. naja, du kannst es sicher trotzdem lesen.

thorsten


------------------
Thorsten Wandersmann
SuSE GmbH, Nuernberg


[Dieser Beitrag wurde von Thorsten Wandersmann am 15. September 2000 editiert.]

[Dieser Beitrag wurde von Thorsten Wandersmann am 15. September 2000 editiert.]

thommy
16-09-2000, 00:28
Zu 1:
<ul>
ls -l bringt bei leeren Verzeichnissen immer 3 Einträge "gesamt", "." und ".."</li>
Der korrekte Aufruf wäre z.B. "ls | wc -w".</li>
Eine Kommandosubstitution kannst Du einer Variablen zuweisen:
bla=$(ls|wc -w); deren Inhalt kannst Du dann mittelst "test" vergleichen</li>
[/list]

Zu 2:

Den nächsten Durchlauf der umgebenden Schleife kannst Du durch einen Aufruf von "continue" beginnen.

Zu 4:

Ein Beispiel:

<pre>
set $(ls *.exe *.ins *.dll)

for i do
suffix=${*.}
case "$suffix" in
exe ) echo "exe-Datei";;
ins ) echo "ins-Datei";;
dll ) echo "dll-Datei";;
* ) echo "unbekannt";;
esac
done
</pre>

Ob das Beipiel funktioniert, kann ich leider derzeit nicht testen, prinzipiell müsste es so gehen...

Thomas

16-09-2000, 09:29
Hi,
mein kopiertes Script ist schön formatiert, leider wird es nicht übernommen, sorry.
Werner

thommy
18-09-2000, 09:07
"mkdir" nur ausführen, falls das Verzeichnis nicht existiert:

<code>test -d ../ausgabe/$i &#0124; &#0124; mkdir ../ausgabe/$i</code>


Um den nächsten Schleifendurchlauf zu beginnen, ist <code>continue</code> zu verwenden.

Und.. um die Formatierung des Skripts beizubehalten, musst Du dieses in &lt;pre&gt;...&lt;/pre&gt; einschließen...

Thomas