Skip to content

Drachenboot besiegt bash

Nachdem ich nun wochenlang nichts neues zu berichten wusste, ist es nun mal wieder Zeit für einen neuen Eintrag.
Am Wochenende, genauer gesagt am Samstag, war das Drachenboot-rennen im Medienhafen. Unsere Firma hatte dieses Jahr zum ersten mal daran Teil genommen, und angesichts der Tatsache, das wir quasi noch Anfänger waren und auch das Wetter gegen uns war, kann man unsere Platzierung auf dem 15. Platz (bei 40 Teilnehmern) durchaus als Erfolg werten!

Das Wetter an sich war eigentlich nicht schlecht - nur dumm, dass es immer genau dann geregnet hat wenn wir am paddeln waren. Und um das ganze noch zu toppen, hat es natürlich pünktlich wenn wir fertig waren wieder aufgehört. Das ganze erinnerte mich an diverse Cartoons, wenn die kleine Regenwolke genau über dem Kojoten steht und ihn verfolgt.
Wir haben schon mit dem Gedanken gespielt, den Namen unseres Teams nächstes Jahr in "Gewitterfront" zu ändern.

So und um dem Thema dieses Blogs noch gerecht zu werden: ein kleiner Exkurs darüber, das auch die bash beschissen sein kann!
Die Problemstellung war diesmal: alle Verzeichnisse in einem bestimmten Verzeichnis durchgehen und gucken ob eine Datei mit einem bestimmten Namen darin liegt.
Klingt einfach? Im Grunde ja, aber... nun gut, gehen wir der Reihe nach.
Mein erster Ansatz war natürlich jener hier:
for g in `ls -1b ${directoryName}`
do
  # Verzeichnis checken
done

Zur Erläuterung: die optionen -1 und -b von ls bewirken, das jede Datei auf einer extra Zeile ausgegeben wird, und das Leerzeichen escaped werden. Man sollte annehmen, dass das funktioniert - tut es aber nicht!
Wenn man in ${directoryName} ein Verzeichnis "ein verzeichnis" hat (man beachte das Leerzeichen), dann wird er die Schleife einmal für "ein" und einmal für "verzeichnis" durchlaufen! Auch wenn man dem ls die Option "-Q" übergibt, welche dafür sorgt das die Ergebnisse gequoted werden, ändert das nichts daran.

Es gibt auch keine Möglichkeit in irgendeiner Form zu definieren, das die for-schleife nur noch linebreaks und keine Leerzeichen als Separator benutzen soll.
Und so blieb mir nur die Möglichkeit mich zu ärgern, und das ganze wie folgt um zu schreiben:
`ls -1b {directoryName} > temporaryList.txt`
while read g
do
  # das selbe wie oben
done < temporaryList.txt

Das ist natürlich reichlich unschön, weil man hier eine temporäre Datei anlegen muss, aber scheinbar der einzige Weg.

Nachtrag
Wie ich später heraus fand, ist das durchaus nicht der einzige Weg.
Mit einem Kniff geht es auch ohne temporäre Datei:
while read g
do
  echo "$g";
done < <(ls -1b /path/to/target)

Wichtig ist dabei das Leerzeichen zwischen den beiden '<' - das sorgt dafür, dass man quasi eine Art virtuelle, temporäre Datei hat, von der aus gelesen wird.