Skip to content

Hashes in der Bash ...

Weil ich es gerade für einen Kollegen gebraucht habe.

Ein eher selten genutztes Feature in der Bash sind assoziative Arrays (Hashes). Ab Bash Version 4 geht das ganz ohne Hilfskonstrukte.

#!/bin/bash

declare -A dns=(
    [mond]=192.168.0.1
    [erde]=192.168.2.3
    [saturn]=192.168.7.8
)

echo "Alle Keys:   ${!dns[@]}"
echo "Alle Values: ${dns[@]}"
echo

for host in ${!dns[@]}; do
    ip=${dns[${host}]}
    echo "${host} hat die IP-Adresse ${ip}"
done


Schlüssel und Werte dürfen "natürlich" auch Leerzeichen enthalten. Dann müssen diese allerdings - wie bekannt - in Anführungszeichen stehen.

Ergebnis des Skriptes:

Alle Keys:   erde saturn mond
Alle Values: 192.168.2.3 192.168.7.8 192.168.0.1

erde hat die IP-Adresse 192.168.2.3
saturn hat die IP-Adresse 192.168.7.8
mond hat die IP-Adresse 192.168.0.1

Shell-Magie ...

Je länger ich mich mit der Shell (BaSH in diesem Fall) beschäftige, desto mehr denke ich, dass ich schon alles gesehen habe.

Dieses Konstrukt aber ist mir neu, ja das mit < <(kommando) und vielleicht kann das auch jemand von Euch brauchen.

#!/bin/bash

while read line; do
        echo ${line}
        [[ /${line}/ =~ /.*Suchtext.*/ ]] && break
done < <(tail -f logfile)


Es macht einen tail -f logfile und durchläuft die Schleife für jede Zeile im logfile . Alle Zeilen werden ausgegeben und wenn ein Suchtext im logfile vorkommt, wird die Schleife abgebrochen. Für die, die es nicht kennen, mit =~ kann man ab BaSH Version 3 auch mit regulären Ausdrücken suchen. Die Schrägstriche / werden nur für den Fall benötigt, dass im logfile auch Leerzeilen vorkommen.

Das Konstrukt umschifft einige Schwächen, die ähnliche Beispiele haben, die mit anderen Arten von Ein- und Ausgabeumlenkung arbeiten.

Wer es nicht glaubt, kann mal das Folgende probieren:

#!/bin/bash

tail -f logfile | while read line; do
        echo ${line}
        [[ /${line}/ =~ /.*Suchtext*/ ]] && break
done

Shell Style Guide ...

Bei Google gibt es einen Shell Style Guide, den ich wirklich jedem nur ans Herz legen kann.

Die Regeln sind sinnvoll und helfen, dass Skripte auch eine Woche nachdem sie geschrieben wurden noch verstanden werden können. :-)

Einiges ist sicherlich diskussionswürdig und Geschmackssache, ich würde Perl statt Python für längere Skripte nehmen, aber in Summe ist das Dokument prima.

Brace Expansion ...

Viele kennen die Brace Expansion, einen Mechanismus von Shells, insbesondere der GNU Bash gar nicht.

Brace Expansion lässt sich nicht so leicht übersetzen, vielleicht am besten mit Klammererweiterung.

{a,b,d} erzeugt a b d, dieser Term wird dort ersetzt, wo er eingesetzt wird ab{a,b,d} ergibt aba abb abd. {1..10} macht 1 2 3 4 5 6 7 8 9 10, {01..04} entsprechend mit führenden Nullen 01 02 03 04. Das geht auch mit Inkrementen {1..9..2} entspricht den ungeraden Zahlen 1 3 5 7 9 oder bei Buchstaben {a..f} macht a b c d e f und {a..f..2} ergibt a c e. Das ganze ist verschachtelbar {a{1,2},c,e} erzeugt a1 a2 c e.

Manche nutzen es, um einfach eine Reihe an Verzeichnissen zu erstellen.

mkdir M{e,a}{i,y}er
mkdir cd{01..10}
mkdir /home/{dirk,jupp,hans}/{.ssh,vorlagen,arbeit}


Aber es gibt auch eine ganz einfache Anwendung, die jeden Tag hilft, Erstellung von Backup-Dateien:

cp datei{,.bak}
cp datei{,von-heute}.txt