Verzeichnisse packen und loeschen

cat1510

Well-Known Member
Hallo Leutz,

ich moechte in einem Verzeichnis alles Unterverzeichnisse in ein RAR's packen und danach alle Verzeichnisse loeschen.

Quasi gibt es im Verzeichnis /temp die Unterverzeichnisse a b c d e f g h

Nach dem Script soll im Verzeichnis /temp

a.rar
b.rar
c.rar

und so weiter sein. Die Verzeichnisse sind dann geloescht.

Das ganze soll ein Shell Skript sein.

Mir fehlt eine Idee, wie ich das auf einer Zeile loesen kann.

Danke fuer Eure Muehe.

CAT
 
cat1510 schrieb:
Hallo Leutz,

ich moechte in einem Verzeichnis alles Unterverzeichnisse in ein RAR's packen und danach alle Verzeichnisse loeschen.

Quasi gibt es im Verzeichnis /temp die Unterverzeichnisse a b c d e f g h

Nach dem Script soll im Verzeichnis /temp

a.rar
b.rar
c.rar

und so weiter sein. Die Verzeichnisse sind dann geloescht.

Das ganze soll ein Shell Skript sein.

Mir fehlt eine Idee, wie ich das auf einer Zeile loesen kann.

Danke fuer Eure Muehe.

CAT


Was denn nun ? Skript oder Einzeiler ?

Ich würde mit find ... -type d die Verzeichnisse rausfischen und dann in einer for-Schleife jedes Verzeichnis erst raren und dann rm -rfen. Fertig ist die Laube. :)

Kann man sicher auch noch unleserlicher .. äh .. sorry .. kompakter machen, aber sollte funzen.
 
hi,

dann wuerde ich es lieber in einem Script abhandeln.

Ich dachte nur, es muss ein Einzeiler sein, weil er die Zerzeichnisse in einem Schritt in RAR packen sollte.
Kann auch ein Denkfehler gewesen sein.

Danke fuer Deine Antwort.


CAT
 
Wenn du alle Verzeichnisse in ein einziges RAR packen willst, geht das in einem Arbeitsschritt. Aber wenn du mehrere Verzeichnisse jeweils in unterschiedliche Archive packen willst, dann mußt du das zwingend jeweils in einem eigenen Schritt machen. So was macht man, wie CAMISOLITE schon schrieb, in einer for-Schleife:
Code:
cd /tmp
for DIR in a b c d e f g h
do
  rar <Schalter zum Erstellen, keine Ahnung> "$DIR".rar "$DIR"  \
  &&  rm -rf "$DIR"
done
Unter Einzeilern dagegen versteht man eher Konstrukte, die man mal schnell auf einer einzigen Befehlszeile eintippen kann. Da du aber ein Shell-Skript wolltest, ist das sowieso uninteressant.
 
Nee Chaot ist moechte jedes in ein eigenes packen.

Also mit dem find bin ich noch nicht vertraut.
Haette mir die dir's alle mit ls und awk ausgeben lassen.
Wie macht man das denn mit find?

Dann habt Ihr natuerlich recht, dass ein Einzeiler was anderes ist.


CAT
 
Also man kann mit:

# find /dir -type d

alle Verzeichnisse anzeigen lassen.

Ok der zeigt aber auch alle Verzeichnisse in den Verzeichnissen an.
Das will ich nicht.
Nur eine Verzeichnis Ebene tiefer und kein / hinten dran.

Cool mit find kann man ja auch eine ganze Menge machen.
Sogar direkt befehle ausfuehren im Suchergebnis.


CAT
 
cat1510 schrieb:
Nee Chaot ist moechte jedes in ein eigenes packen.
Was heißt da "nee"? Nichts anderes macht das Code-Beispiel doch. Falls nicht, hast du dein Vorhaben falsch beschrieben.

cat1510 schrieb:
Haette mir die dir's alle mit ls und awk ausgeben lassen.
Wie macht man das denn mit find?
Willst du sämtliche Verzeichnisse in /temp derart verarbeiten? Dann hat CAMISOLITE die Lösung schon angedeutet. Das packst du einfach als Liste in den for-Schleifenkopf.

cat1510 schrieb:
Also mit dem find bin ich noch nicht vertraut.
Einfach mal die Manpage lesen. Im Prinzip brauchst du nur -type, -depth und (je nach Plattform) -print für das Rundum-Sorglos-Paket.
 
Neeeeee wir haben uns falsch verstanden.

Mit der Depth habe ich nicht gelesen.
Is ja geil.... Es klappt!

Du hast das alles schon richtig verstanden. Habe mich nur falsch ausgedrueckt.
War auch schon spaet. ;)


Nun werde ich mal die for Schleife lernen... :)
Jeden Tag was Neuse.




Danke Euch.

CAT
 
find -depth kann er auch bequem mit nem test ersetzen.

Code:
cd /tmp
for i in *;do test -d "$i" && echo "rar a $i.rar $i && rm -rf $i";done
Das ganze gibt erstmal nur mit echo aus, was es tun wuerde, wenn einem das passt pappt man einfach ein "|sh" hintenran und los gehts.

Achtung: Sonderzeichen im Verz.namen machen Probleme, ebenso Verz. die mit . beginnen.
 
GENIAL!!!

Das ist doch fast ein Einzeiler...
Ja es wird aber ein Script.
Und ich werde es auch hier posten.

An genau das habe ich gedacht.
*g werde noch eine Menge lernen und manpages lesen. *Versprochen*

Was mir nicht klar ist, wie das mit find geht, weil es immer den kompletten Pfad zurueck gibt.


DANKE!



CAT
 
cat1510 schrieb:
Das ist doch fast ein Einzeiler...
Wenn du das unter einem Einzeiler verstehst, dann kannst du aus so gut wie jedem Skript einen Einzeiler machen, indem du alle Zeilenumbrüche durch Semikolon ersetzt.

cat1510 schrieb:
Was mir nicht klar ist, wie das mit find geht, weil es immer den kompletten Pfad zurueck gibt.
Du kannst den letzten Teil eines Pfades mit basename(1) erhalten, das Gegenstück ist dirname(1). Aber damit hast du doch hier gar kein Problem:
Code:
for DIR in $(find /temp -type d -depth 1)
do
  rar <Schalter zum Packen> "$DIR".rar "$DIR"
done
cat1510 schrieb:
Nun werde ich mal die for Schleife lernen...
In diesem Zusammenhang solltest du dich auch mit der Funktion von $IFS beschäftigen.
 
ok ok,

was in keinster weise heissen soll, dass Deine Loesung nicht funktioniert oder schlechter ist.
Du hast recht, werde das in dem Script ja auch ein wenig mehrzeilig gestalten.
Mit test -d arbeite ich schon haeufiger, darum erschien es mir schneller logisch.

Was ist denn $IFS? Bei Google kommt dazu nichts.



CAT
 
cat1510 schrieb:
Was ist denn $IFS? Bei Google kommt dazu nichts.
Hast du ein anderes Google als ich? Wenn ich nach "$IFS" suche, kommt zumindest das "IfS - Institut für Sachverständigenwesen", das "Institut für Schulentwicklungsforschung" und ähnliches. Über Google/BSD findet man aber z.B. http://www.bsdbooks.net/shells/scripting/fr/internalvariables.html (mit schönen Beispielen, nicht nur zu $IFS - falls Französisch kein Hindernis ist). Ansonsten erklärt auch bash(1) kurz den Zweck. Wenn du mehr Literatur brauchst, suche mal nach "Internal Field Separator", da sollte sich einiges finden lassen.

Der Sinn ist der, daß du da zumindest das Leerzeichen rausnehmen solltest, sonst macht das Skript bei Verzeichnisnamen mit Leerzeichen sofort Ärger. Den Tab kannst du dir auch sparen, du brauchst hier eigentlich nur Return.
 
Hoer mal Alter ich bin kein MCSE!!! Ok? :eek:

Fruehstueck ist auch vorbei. ;)

Ich dachte mir schon, dass "$IFS" suche, kommt zumindest das "IfS - Institut für Sachverständigenwesen", nicht zum Thema hier passt.

Und ja franzoesisch ist ein Hindernis, dafuer English und Russisch nicht. :P

Haettest Du natuerlich Field Seperator geschrieben, waere mir einiges klarer.
Kenn ich naemlich auch von awk... zum Beispiel.



CAT
 
Sooo nun nochmal das ganze Script fertig und getestet.


Was tut es?

Es packt Unterverzeichnisse in einem Verzeichnis in einzelne rar Dateien.
Danach loescht es alle Unterverzeichnisse.
Gibt es Dateien im Archivzerzeichnis werden diese nicht komprimiert.


Habe das nochmal auseinandergenommen und nun sind auch Verzeichnisse mit Leerstellen kein Problem.

Das Copyright koennt Ihr ignorieren.
Den Loeschbefehl fuer die Verseichnisse habe ich auch auskommentiert,
damit nichts ungewolltes passiert.


Code:
#!/bin/sh
# 		Copyright by BYTEWORKER
# 	          for more information
#	       contact cat@byteworker.com

set -xv

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin

ARCHIVPATH=/data/archiv							# Der Pfad in dem die Daten archiviert werden sollen.
PASSWORD=test								# Password fuer die erzeugten rar dateien.		
ERRORMAILADRESS=			#error@archiv.com		# E-Mail Empfaenger bei Problemen
CUSTOMNOTIFY=				#true | false			# Kundenmitteilung an oder aus schalten.
CUSTOMMAILADRESS=			#franz@hugencamp.com		# Kunden E-Mail Adresse.
CUSTOMMAILADRESSLIST=			#"-c bar@example.com,help@test.de" # Liste mit Kunden, die auch eine mail erhalten.
CUSTOMERNAME=				#'Franz Hugenkamp'		# Kundenname
NOTIFYFILE=/tmp/notify.log						# Wohin das Notify File generiert wird.
LOGFILE=/tmp/archiv.log							# Wo alles geloggt wird.


############## Funktionen #########################

printline() {								# Fuegt eine tolle Formatierung ein und schreibt in messages
  echo -e "$LINEHEADER $LINETEXT $LINETAIL"
  logger $LINETEXT
  }
  
printline2() {								# Rechnet die Dauer des Archivvorgangs aus.
   ENDE=`date -u +%s`
   TIME=`echo $ENDE - $START | bc`
   echo -e "$LINEHEADER Dauer des Archivierungsvorgangs `date -u -r $TIME +"%H:%M:%S"` Stunden:Minuten:Sekunden. $LINETAIL"
   }
 
notify() {								# Die Notify E-Mail an den Kunden.
   if test $CUSTOMNOTIFY = true						# Erstellt aus den Saetzen, die in eine Datei
   	  then								# geschrieben werden.
	   touch $NOTIFYFILE
	     echo -e "\n\nHallo $CUSTOMERNAME!\n" >> $NOTIFYFILE
	     echo -e "Alle Aufgaben erfolgreich beendet am `date`." >> $NOTIFYFILE
	     echo -e "Dauer des Archivierungsvorgangs `date -u -r $TIME +"%H:%M:%S"` Stunden:Minuten:Sekunden." >> $NOTIFYFILE
	     echo -e "\n\nMit freundlichen Gruessen, Ihr Archivierungs Daemon... ;)" >> $NOTIFYFILE
	     mail -s "BACKUP MESSAGE! `uname -n`" $CUSTOMMAILADRESSLIST -b $ERRORMAILADRESS $CUSTOMMAILADRESS < $NOTIFYFILE
	     sleep 2
	     rm -f $NOTIFYFILE
    fi
    }

#####################################################

if test ! -d $ARCHIVPATH
          then
	  LINETEXT="Das Verzeichnis $ACHIVPATH existiert nicht."	  	# Prueft ob das Archivverzeichnis existiert.
	  printline
	  LINETEXT="Bitte ueberpruefen Sie den Archiv Pfad."
	  printline
	  mail -s "ARCHIV WARNING! `uname -n`" $ERRORMAILADRESS < $LOGFILE	# Sendet eine Error Mail.
	  exit 1
fi

	    
START=`date -u +%s`								# Festhalten des Startzeitpunktes.

cd $ARCHIVPATH									# In das Archiv Verzeichnis wechseln.
for i in *
      do 
	 test -d "$i" 
	      if [ $? != 0 ]							# Schleife fuer die Verzeichnisse, die komprimiert werden.
	           then
		   echo "$i ist eine Datei und kein Verzeichnis."  
		   echo "Es geht weiter!"
	           else
	 	   echo "Das Verzeichnis $i wird archiviert."
		   rar a -p$PASSWORD -m5 -idq -- "$i.rar" "$i" 			# Der Packbefehl.
	      
	      	   if [ $? != 0 ]a						# Ein Test ob das Packen erfolgreich war.
	           	then
	            	LINETEXT="Das Verzeichnis $i konnte nicht archiviert werden!"
		    	printline
	            	mail -s "ARCHIV WARNING! `uname -n`" $ERRORMAILADRESS < $LOGFILE
	            	exit 1
  		    	else
		    	echo "Es wird $i geloescht"
			#rm -rf "$i"						# Das Verzeichnis wird geloescht.
		   fi
	      fi
done

LINETEXT="Archivierung erfolgreich abgeschlossen."
printline
printline2
notify

2>&1 >> $LOGFILE


Ueber ein Feedback wuerde ich mich sehr freuen.

MFG
CAT
 
Zuletzt bearbeitet:
cat1510 schrieb:
Was ist denn $IFS? Bei Google kommt dazu nichts.

sh(1) ist in der sh(1) (also manpage) dokumentiert, nicht auf Google.

Wenn du in "man sh" ein wenig nach IFS suchst, kommst du schnell drauf, wofuer das gut ist. (Nur so als tipp, manpages sind nuetzlich.)
 
Zurück
Oben