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.