Dateien mit rsync schneller löschen

2. Juni 2013 at 19:38

terminal2Das Linux Tool ‚rsync‘ ist vielen Admins bekannt. Man kann damit Dateien lokal oder über eine SSH-Verbindung schnell und einfach abgleichen. Daher wird Rsync gerne für Backups oder Testumgebungen genutzt.

Einen sehr kreativen Einsatz von Rsync habe ich kürzlich kennen gelernt: Rsync kann große Mengen von Dateien schnell löschen. Überraschenderweise sogar schneller, als das rm-Kommando.

Hier der Versuch:

Im ersten Schritt erstellen wir ein Testverzeichnis und legen dort 100.000 Dateien an. Dann löschen wir die Dateien mit rm auf die übliche Art und Weise wieder und messen dabei die Zeit:

# Testverzechnis anlegen
mkdir /tmp/test-speed-rm

# 100.000 Dateien anlegen
for NUM in $(seq 1 100000); do touch /tmp/test-speed-rm/testfile-$NUM; done

# Dateisystem-Caches leeren
sync

# Alle Dateien mit 'rm' löschen und Ausführungsdauer ausgeben
time rm /tmp/test-speed-rm/*

Das Ergebnis auf meinem System:

real 0m10.382s
user 0m10.235s
sys 0m0.136s

Nun wiederholen wir den Test, doch diesmal legen wir zusätzlich ein leeres Verzeichnis an und benutzen dann rsync, um das leere Verzeichnis in das volle Verzeichnis synchronisieren zu lassen. Rsync wird feststellen, dass im Zielverzeichnis viele Dateien sind, die im Quellverzeichnis nicht vorhanden sind, und diese dann löschen:

# Altes Testverzeichnis komplett löschen (gleiche Ausgangssituation für beide Tests!)
rm -rf /tmp/test-speed-rm

# Testverzechnis anlegen
mkdir /tmp/test-speed-rm

# 100.000 Dateien anlegen
for NUM in $(seq 1 100000); do touch /tmp/test-speed-rm/testfile-$NUM; done

# Dateisystem-Caches leeren
sync

# Leeres Verzeichnis anlegen
mkdir /tmp/empty

# Mit RSYNC das leere Verzeichnis in das zu löschende Verzeichnis synchronisieren
time rsync -a --delete /tmp/empty/ /tmp/test-speed-rm/

Überraschenderweise löscht Rsync viel schneller:

real 0m4.398s
user 0m0.468s
sys 0m3.854s

Wirklich interessant, während rm inode für inode löscht und dabei knapp 10 Sekunden benötigt, schafft rsync die gleiche Arbeit in einem Rutsch in nur etwas über 4 Sekunden.

Übrigens: Auch ‚find -delete‘ oder ‚find | xargs rm‘ funktionieren nicht schneller. Bei größeren Dateimengen scheint rsync wirklich das schnellste Tool zu sein.

Rettet das Datum!

18. März 2013 at 22:44

Das kleine Kommando ‚date‘ der Linux-Shell wird oft mächtig unterschätzt. Man kann das Ausgabeformat setzen und sogar das Datum relativ zum heutigen Tag bestimmen. Hierfür gibt es viele Anwendungsfälle:

# Datum ausgeben
date
Mon Mar 18 20:00:00 CET 2013
# Das Datum von gestern
date -d "yesterday"
Sun Mar 17 20:00:00 CET 2013
# Das Datum von vor 2 Tagen
date -d "2 days ago"
Sat Mar 16 20:00:00 CET 2013
# Das Datum im ISO-Format
date +"%Y-%m-%d"
2013-03-18

Hier nun eine Kombination daraus:

# Das Datum von gestern im ISO-Format
date +"%Y-%m-%d" -d "yesterday"
2013-03-17

Nun erzeugen wir einen Dateinamen:

date +"something-%Y-%m-%d.log" -d "yesterday"
something-2013-03-17.log

Wenn wir den Namen in einer Variable benötigen:

FILENAME=$(date +"something-%Y-%m-%d.log" -d "yesterday")
echo "$FILENAME"

Ein anderer Anwenungsfall: Bestimmen wir die Zeit zwischen 2 Zeitpunkten:

START=$(date "+%s")
(do something)
ENDE=$(date "+%s")
let "DIFF = $ENDE - $START"
echo "$DIFF Sekunden"

Nun erhalten wir die Zeit-Differenz in Sekunden. Aber was sagt uns schon 2800 Sekunden? Auch hier kann date helfen, die Zeit umzurechnen:

date -d "00:00:00 $DIFF seconds" "+%H:%M:%S"
00:46:40

Das obige Script lief also 46 Minuten und 40 Sekunden. So läßt sich dem nächtlichen Backup-Script schnell beibringen, wie es seine Laufzeit auszugeben hat.

Noch ein Trick: Mit folgendem Befehl kann man die 3 Variablen $DAY, $MONTH und $YEAR in einer Zeile setzen:

eval $(date "+DAY=%d; MONT=%m; YEAR=%Y")

Nun läßt sich mit ‚echo $YEAR‘, ‚echo $MONT‘ oder ‚echo $DAY‘ das Datum im Script abfragen.

Ach ja, wie alt bin ich eigentlich?

BIRTHDAY="1975-01-10"

BDAY_SEC=$(date "+%s" -d "$BIRTHDAY")
NOW_SEC=$(date "+%s")

let "DIFF_SEC = $NOW_SEC - $BDAY_SEC"
echo "Alter: $DIFF_SEC Sekunden"

let "DIFF_DAYS = $DIFF_SEC / 60 / 60 / 24"
echo "Alter: $DIFF_DAYS Tage"

Es gibt so viele Anwendungsfälle. Also, rettet das Datum! :-)

Mehr zum Thema date: hier

tree

24. Dezember 2012 at 07:00

TreeFrohe Weihnachten!

Und weil sich heute alles um den Weihnachtsbaum versammelt, will ich das „tree“ Utility mal vorstellen. Mit „apt-get install tree“ läßt sich das Tool unter Debian installieren. Es zeigt Verzeichnisbäume auf der Konsole in einer Linien-Hierarchie an. Nichts besonderes, aber um sich einen Überblick zu verschaffen, kann es selbst hilfreich sein.

Die wichtigsten Parameter für den Einstieg:

  • -a zeigt auch versteckte Dateien an
  • -d zeugt nur Verzeichnisse, keine Dateien (sonst werden auch alle Dateien mit angezeigt)
  • -L <num> zeigt nur <num> Ebenen an.

Möchte man zum Beispiel mal seine Struktur im /usr/local Verzeichnis kennen lernen, geht das so:

# tree -d /usr/local/
/usr/local/
├── bin
├── etc
├── games
├── include
├── lib
├── man -> share/man
├── sbin
├── share
│   ├── ca-certificates
│   ├── fonts
│   ├── man
│   ├── sgml
│   │   ├── declaration
│   │   ├── dtd
│   │   ├── entities
│   │   ├── misc
│   │   └── stylesheet
│   └── xml
│   ├── declaration
│   ├── entities
│   ├── misc
│   └── schema
└── src

Ach ja, noch ein zweiter Tipp, weil ja Weihnachten ist:

pstree ist zwar ein ganz anderes Tool, aber macht das gleiche mit laufenden Prozessen (also ps mit Tree-Ansicht).

Viel Spaß beim Ausprobieren.