bash Skript und Multicore Prozessoren

Wenn man viel mit bash-Skripten macht, kommt man oft an das Problem, dass man Multicore-Prozessoren nicht richtig ausreizen kann. Nehmen wir das Beispiel, dass man alle *.tif Bilder in einem Ordner mit Hilfe von imagemagick zu TIFF/JPEG komprimieren moechte. Das Skript:

for i in *.tif ; do convert $i -compress JPEG $i; done

macht dieses, ein Bild nacheinander. Man koennte das ganze nun schneller machen, indem man einfach jeden convert in eine Subshell packt:

for i in *.tif ; do convert $i -compress JPEG $i &; done

kommt dann aber sehr schnell in Schwierigkeiten, wenn dann nen Ordner mit z.B. 500 Bildern hat und dann auch 500 Subshells. Eine elegantere Loesung ist, eine maximale Anzahl von Prozessen anzugeben die nicht ueberschritten wird und dann abzuarbeiten. Dafuer laesst sich xargs gut benutzen. Wenn man z.B. maximal vier Prozesse haben moechte geht das mit:

find *.tif -print0 | xargs -0 -I {} -P 4 convert -compress JPEG {} {}

Dabei bedeuten die Parameter bei find:

  • -print0 -> print the full file name on the standard output, followed by a null character

und bei xargs:

  • -0 -> Input  items  are  terminated  by a null character instead of by whitespace
  • -I {} -> Replace string
  • -P 4 -> Run  up  to max-procs processes at a time

Der String replace wird genutzt um zweimal das gleiche Argument zu uebergeben. Arbeitet man mit -n 2 werden zwei aufeinanderfolgende Argumente uebergeben.

(bash)Notizen…

  • alle Dokumente rekursiv mit der Gruppe tomcat55 anlegen / setgid:
chgrp tomcat55 /home/myfolder
chmod g+s /home/myfolder
  • alle Dateien von *.TIF in *.tif umbenennen
for i in `ls *.TIF`; do mv $i `echo $i| sed 's/TIF/tif/g'` ; done
  • alle *.tif Dokumente in einem Ordner fortlaufend numerieren
i=0; for j in `ls *.tif` ; do i=`echo $i + 1|bc` ; mv $j $i.tif ; done
  • alle Dokumente in einem Ordner fortlaufend numerieren mit 8 Stellen
i=0
stellen=8
 
for j in * ; do
  i=`echo $i + 1|bc` ;
  NEU=`printf "%.${stellen}i\n" $i`.tif ;
  mv $j $NEU
 
done

LDAP-Backup erstellen

Ich bin ein Freund vom Plain text. Damit laesst sich IMHO immer noch am besten Arbeiten. Man kann es in alle denkbaren Formate umwandeln, umbiegen, exportieren, was auch immer, und ist deswegen was Backups angeht das Ziel meiner Wahl. Natuerlich habe ich bei dem LDAP-Server das /var/lib/ldap/ im Backuppath mit drin, aber es geht nichts ueber eine Textdatei in der die Werte nochmal als Plain text drinstehen; gleiches gilt uebrigens fuer MySQL-Datenbanken…

Die Backupdatei erstelle ich mit slapcat. Wichtig dabei ist zu beachten, dass die slap* Tools ganz anders arbeiten als die entsprechenden ldap* Gegenstuecke. Beispiel slapadd und ldapadd. Die ldap* Tools sind LDAP-Clients die ueber das LDAP-Protokoll auf die Datenbank zugreifen. Die slap* Befehle aber greifen direkt auf die lokalen Datenbankdateien zu, die Berkley DB = *.bdb Dateien in /var/lib/ldap/. Da die slap* Befehle direkt darauf zugreifen koennen Sie natuerlich nur auf dem Rechner ausgefuehrt werden auf dem der LDAP-Server laeuft, und es ist wichtig, dass der LDAP-Daemon nicht laeuft. Entsprechend ist auch das Backup-Skript was fuer den LDAP laeuft, einmal taeglich per Cron aufgerufen:

#!/bin/bash
 
SLAPCAT=/usr/sbin/slapcat
GZIP=/bin/gzip
BACKUPDIR=/root/ldapbackup/
 
 
# Daemon stoppen
/etc/init.d/slapd stop > /dev/null 2>&1
if [ $? != "0" ]; then
  logger -t "LDAP-Backup:" "Fehler beim Stoppen des slapd Daemons."
  exit 1
fi
 
 
# Backup in Textdatei erzeugen
$SLAPCAT > $BACKUPDIR/$(date +%Y%m%d)-ldapbackup.ldif
if [ $? != "0" ]; then
  logger -t "LDAP-Backup:" "Fehler beim Schreiben der Backupdatei mit slapcat."
  exit 1
fi
 
 
# Textdatei komprimieren
$GZIP $BACKUPDIR/$(date +%Y%m%d)-ldapbackup.ldif
if [ $? != "0" ]; then
  logger -t "LDAP-Backup:" "Fehler beim Komprimieren der erstellten Backupdatei."
  exit 1
fi
 
 
# Daemon starten und wenn es ueberall keine Probleme gab dann Erfolgsmeldung in syslog
/etc/init.d/slapd start > /dev/null 2>&1
if [ $? != "0" ]; then
  logger -t "LDAP-Backup:" "Fehler beim Starten des slapd Daemons."
  exit 1
else
  logger -t "LDAP-Backup:" "Das Backup der LDAP-Datenbank wurde erfolgreich durchgefuehrt."
fi