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

Programmiersprachen Ranglisten ...

Letzte Woche gingen die aktuelle RedMonk Programmiersprachen Rangliste durch die Blogs. Ich kannte die Rangliste tatsächlich noch nicht und habe vorher immer den Tiobe Index zu Rate gezogen- Im Zuge der Recherche zu diesem Artikel habe ich auch noch den Popularity of Programming Language Index gefunden.

Die Ergebnisse sind sehr interessant, weil sie drei verschiedene Messmethoden anwenden, um die gefragtesten Programmiersprachen zu finden.

Der RedMonk Index erscheint alle zwei Jahre und benutzt GitHub und Stack Overflow, um die Rangliste zu erstellen. Damit wird erhofft, die Benutzung (gemessen in Codezeilen) und die Diskussion (Anzahl der Beiträge) in einen Gesamtwert einfliessen zu lassen. Mir persönlich fehlt die Einschränkung auf einen Zeitraum (GitHub: Alle neuen oder alle aktiven Projekte der letzten zwei Jahre beispielsweise). Die für mich interessanten Sprachen finden sich auf folgenden Plätzen:

3 PHP

4 Python

5 Ruby

11 Perl

13 R

Die Berechnung des Tiobe Index ist ein wenig undurchsichtiger, dafür erscheint er aber auch jeden Monat. :-) Die Macher sprechen von einem Popularitätsindex. Die Rangliste wird auf Basis der Ergebnisse in den Suchmaschinen Google, Bing, Yahoo!, Wikipedia, Amazon, YouTube und Baidu ausgerechnet und soll die Anzahl der erfahrenen Ingenieure, Kurse und Drittanbieter berücksichtigen. Wenn man vor der Wahl einer neuen Programmiersprache steht, kann man sich anschauen, was momentan der Trend ist.

6 Python

8 PHP

12 Perl

13 R

16 Ruby

Der letzte im Bunde PYPLI nutzt einzig Google Trends und berücksichtigt nur die Suchen nach Tutorials der Programmiersprachen.

2 PHP

3 Python

10 R

12 Ruby

15 Perl

Interessant ist, dass die Ergebnisse zwar die gleichen Sprachen enthalten, aber in deutlich unterschiedlichen Reihenfolgen.

RedMonk spiegelt die aktive Entwicklung von Open-Source-Projekten wieder, Tiobe zeigt das, was momentan im Markt aktuell ist und PYPLI was gerade gelernt wird. Spannend.

Auch spannend ist, es, sich die Anzahl der registrierten Projekte auf Ohloh anzeigen und nach Sprache auswerten zu lassen.

Globales gitignore ...

Wenn man Dateien aus der Versionskontrolle mit git ausschliessen möchte, kann man im Repository eine Datei .gitignore anlegen. Das ist sinnvoll, wenn es Dateien gibt, die in nur einem Repository ausgeschlossen werden sollen.

Anders ist es, wenn man Backupdateien des Editors ausschliessen möchte. Da in der Regel mehrere Menschen an einem Projekt arbeiten und vielleicht sogar jeder einen anderen Editor benutzt, ist es sinnvoller, dass jeder die Dateien ausschliesst, die seinem Editor entsprechen.

Dazu kann mit dem folgenden Kommando die globale Variable core.excludesfile gesetzt werden, die einen Dateinamen beinhaltet, in der die globalen Ausschlusskriterien zu finden sind.

git config --global core.excludesfile ~/.gitignore_global

Bei mir enthält sie derzeit nur:

*~

Das sind die Backupdateien von vim.

Performanceuntersuchungen ...

Aus aktuellem Anlass muss ich noch einmal auf Bandbreite und Latenz herumreiten und vielleicht noch hinzufügen, dass auch die Anzahl der Anfragen durchaus eine Rolle bei Performance-Betrachtungen spielt.

Wir hatten hier auf einem System massive Performance-Probleme und ich habe relativ schnell herausgefunden, dass ein bestimmter User und von diesem ein bestimmter Prozess für einen grossen Teil der Festplattenlast verantwortlich ist.

Der Applikationsbetreuer war der Meinung, dass das nicht sein könne, da der Teil der Applikation kaum bzw. nur sehr wenig schreibt. Das stimmt, er hat wirklich nicht viel geschrieben, aber dafür wenige Bytes und diese sehr häufig. Das hat die IO-Queue gefüllt und weitere Zugriffe blockiert.

Einige Zeit später hat der Betreuer einfach mal den Prozess beendet und siehe da, die Performance der übrigen Komponenten war sehr hoch.

Lehre, die man daraus ziehen sollte: Glaubt keinem Applikationsbetreuer!

Nein, im Ernst: Es ist wichtig, dass man genau weiss, was eine Applikation tut und noch wichtiger ist es, Performance nicht alleine am Durchsatz fest zu machen. Latenz und Anzahl der Requests spielen ebenfalls eine Rolle.

Cloudprovider ...

Nach meinen wirklich sehr guten Erfahrungen mit DigitalOcean, interessiert mich, welche bezahlbaren Cloudprovider Ihr kennt und womit Ihr Erfahrung habt. Mich interessiert vor allem IaaS (Infrastructure as a service).

Für die einzelnen Begrifflichkeiten verweise ich auf diesen Artikel hier oder den Cloud-Computing-Artikel in der Wikipedia.

Amazon EC2

DigitalOcean

Google Compute

JiffyBox (in Deutschland)

Linode

Microsoft Azure

Rackspace

teutoStack (in Deutschland)

Tiny Tiny RSS update daemon und systemd ...

Um den update daemon von Tiny Tiny RSS unter systemd (CentOS 7) auch bei einem Serverneustart direkt verfügbar zu haben, habe ich das unten stehende Unitfile geschrieben, vielleicht hilft es auch Euch.

Man kann von systemd halten, was man möchte, ich finde es aber deutlich eleganter als System V Initskripte.

[Unit]

Description=Tiny Tiny RSS update daemon

After=network.target mariadb.service

Requires=mariadb.service

[Service]

User=apache

Group=apache

WorkingDirectory=/⁠var/⁠www/⁠html/⁠ttr

Type=simple

StandardOutput=null

StandardError=syslog

ExecStart=/⁠usr/⁠bin/⁠php ./⁠update_daemon2.php

PrivateTmp=true

InaccessibleDirectories=/⁠home /⁠root /⁠boot /⁠opt /⁠mnt /⁠media

ReadOnlyDirectories=/⁠etc /⁠usr

[Install]

WantedBy=multi-⁠user.target

Einfach nach /lib/systemd/system/ttrss-update.service kopieren und mittels systemctl daemon-reload einlesen (den Befehl muss man auch ausführen, wenn man das Skript manuell ändert).

Testen mit

systemctl start ttrss-update
systemctl status ttrss-update

und, wenn alles erfolgreich war mit dem folgenden Befehl aktivieren:

systemctl enable ttrss-update

Git swapped beim Packen ...

Von Zeit zu Zeit lohnt es sich Git-Repositories neu zu packen oder den Müll weg zu bringen (mittels "garbage collection, der Befehl ist git gc).

Auch beim Auschecken oder Klonen von grossen Repositories packt Git neu.

Da ich mit den Standard-Einstellungen regelmässig ware Swap-Orgien erlebt habe, lohnt es sich, die Ressourcen für Git zu begrenzen.

In der Standard-Einstellung benutzt Git pro Core und Hyper-Threading je einen Thread. Da Hyperthreading keinen "echten Prozessor" zur Basis hat, steht aufgrund vieler Kontextwechsel das System nahezu still. Ein System mit zwei Kernen und Hyperthreading wird von Git mit vier Threads konfiguriert und jedem Thread steht im Standard der komplette Arbeitsspeicher zur Verfügung.

Das ist ein bisschen viel. Und die folgenden Konfigurationsoptionen begrenzen das ein wenig.

git config --global pack.threads 2
git config --global pack.windowMemory 1073741824

git config --global pack.depth 250
git config --global pack.window 250

Die genaue Beschreibung der einzelnen Optionen lassen sich auf der git-config-Manpage nachlesen.

Das Repack-Skript auf der oben verlinkten Webseite hat sich damit natürlich auch verändert.

#!/bin/bash

case $(uname) in
    "Linux")
        renice -n 19 -p $$
        ionice -c 2 -n 7 -p $$
        ;;
    "SunOS")
        renice -n 19 -p $$
        ;;
esac

start_directory=$PWD
for i in $(find ${start_directory} -name '.git' -type d); do
    du -hs ${i}/..
    cd ${i}/..

    git gc
    git repack -a -d

    du -hs ${i}/..
    echo
done

Dieses Skript ist Teil meines littlehelpers-Repositories auf GitHub.

Feedly Theme für Tiny Tiny RSS ...

Einer der grössten Kritikpunkte an Tiny Tiny RSS - neben der Tatsache, dass der Hauptentwickler ein Arctrl-wctrl-ww sozial schwierig ist - ist das Aussehen.

Christian Grube hat mich bei Google+ schon vor Monaten auf dieses wirklich hervorragende Theme für Tiny Tiny RSS hingewiesen, ich kann es nur empfehlen:

Das Feedly-Theme für Tiny Tiny RSS.

Der Screenshot ist aus diesem Forenthread.

Benchmarking ...

Man kann viel über Tools lernen, wenn man nachvollziehbare Messungen macht.

Für mich hat sich als sinnvoll erwiesen, fünf Mal zu messen. Die beste und die schlechteste Messung wird gelöscht ("Ausreisser") und aus den verbleibenden drei Messungen nehme ich den Mittelwert.

Die Messungen für den Artikel dd vs. fallocate vs. truncate ... habe ich mit diesem Skript gemacht:

#!/bin/bash
set -o errexit

# echo 'sync ; time (dd if=/dev/zero of=10gig.dd count=20971520 ; sync)'
# echo 'sync ; time (dd if=/dev/zero of=10gig.dd bs=1024 count=10485760 ; sync)'
# echo 'sync ; time (dd if=/dev/zero of=10gig.dd bs=10240 count=1048576 ; sync)'
# echo 'sync ; time (dd if=/dev/zero of=10gig.dd bs=20480 count=524288 ; sync)'
# echo 'sync ; time (fallocate -l 10G 10gig.fallocate ; sync)'
echo 'sync ; time (truncate -s 10G 10gig.truncate ; sync)'
for i in $(seq 1 5); do
        sync ; time (truncate -s 10G 10gig.truncate ; sync)
        rm 10gig.truncate
done

Dabei habe ich das Kommando eingesetzt, was ich gerade getestet habe.

Interessant ist, wie sich die Blocksizes bei dd auf die wirkliche Schreibperformance auswirken ... nämlich minimal. Hier kommen nur die mittleren der fünf Werte, die komplette Liste der Messwerte lässt sich hier sehen.

sync ; time (dd if=/dev/zero of=10gig.dd count=20971520 ; sync)
20971520+0 records in
20971520+0 records out
10737418240 bytes (11 GB) copied, 36.6231 s, 293 MB/s

real    2m2.442s
user    0m2.772s
sys     0m33.771s

#####

sync ; time (dd if=/dev/zero of=10gig.dd bs=1024 count=10485760 ; sync)
10485760+0 records in
10485760+0 records out
10737418240 bytes (11 GB) copied, 20.5773 s, 522 MB/s

real    1m55.923s
user    0m0.974s
sys     0m19.529s

#####

sync ; time (dd if=/dev/zero of=10gig.dd bs=10240 count=1048576 ; sync)
1048576+0 records in
1048576+0 records out
10737418240 bytes (11 GB) copied, 7.79126 s, 1.4 GB/s

real    1m53.523s
user    0m0.123s
sys     0m7.667s

#####

sync ; time (dd if=/dev/zero of=10gig.dd bs=20480 count=524288 ; sync)
524288+0 records in
524288+0 records out
10737418240 bytes (11 GB) copied, 6.87154 s, 1.6 GB/s

real    2m8.122s
user    0m0.068s
sys     0m6.808s

Die Cloud ...

Hier ist endlich einmal eine gelungene Übersichtsgrafik, was mit den ganzen Abkürzungen im Cloud-Umfeld "eigentlich" gemeint ist. Die Bausteine bedingen einander.

Software as a Service (SaaS) setzt auf Platform as a Service (PaaS) auf, die als Basis Infrastructure as a Service (IaaS) hat bis schliesslich die Hardware als Fundament erreicht ist.

(Die verlinkten Wikipedia-Artikel sind auch lesenswert).

Nils Magnus/inovex GmbH

Die Grafik ist dem lesenswerten Artikel Cloud Computing - The Name of the Game entnommen und die Veröffentlichung erfolgt mit freundlicher Genehmigung von Nils Magnus und Marius Moise (beide inovex GmbH). Vielen Dank!

PHP Fortgeschrittene ...

In der letzten Woche durfte ich die Schulung PHP Fortgeschrittene im Linuxhotel besuchen. Gehalten wurde die Schulung von Martin "Joey" Schulze.

Das war mein vierter Aufenthalt im Linuxhotel, aber das erste Mal, dass ich dort eine Schulung besucht habe. Und, ich muss sagen, dass die Schulung grossartig war. Danke Joey! (Lasst Euch von seiner Webseite nicht blenden, er hat wirklich etwas drauf).

Erschreckenderweise - als alter Perl-Liebhaber - muss ich gestehen, dass ich auch von den Möglichkeiten von PHP sehr angetan bin. Da kann man mit relativ wenig Aufwand sehr gute objektorientierte Programme schreiben.

Ich habe viel gelernt!

BTW: PHP muss ich lernen, weil ich in der Firma ein in objektorientiertem PHP geschriebenes System übernehme und erweitern soll. Meine Einarbeitung in PHP - also das Basiswissen - habe ich mir mit diesem Buch angeeignet.

Vielleicht ergibt sich darüber auch die Möglichkeit, "die beste Blogsoftware der Welt" in der Programmierung zu unterstützen.

Der Aufenthalt im Linuxhotel war nett und ich habe es sehr genossen, abends meine Eltern besuchen zu können, so häufig kommt das ja leider nicht mehr vor.

Bloonix wird Open-Source-Software ...

Der Monitoring-Dienst Bloonix von Jonny Schulz wird Open-Source-Software. Über den Dienst habe ich hier im Blog schon einmal berichtet.

Ich freue mich sehr darüber, da ich das für eine ausgereifte Lösung halte, die von Jonny mit viel Liebe gepflegt wird. Ausserdem ist es an der Zeit, dass es eine weitere Alternative zu den derzeitigen Platzhirschen gibt.

Well done!

In dem Zusammenhang: Mein privater Server wird von Bloonix überwacht.

Schöne Schriften ...

Ein Kollege von mir hat die "Source"-Schriftserien von Adobe ausgegraben und mir gefallen sie so gut, dass ich meinen Desktop angepasst habe, um sie zu benutzen.

Die drei Schriftarten, um die es geht heissen:

  • Source Code Pro - eine Schriftart, die sich sehr gut als Schriftart für Monospaced-Geschichten eignet, beispielsweise als Default-Schrift in Editoren oder Terminalfenstern.
  • Source Sans Pro - ist perfekt für Menüs und Übersichten auf dem Desktop (ersetzt bei mir Deja Vu Sans).
  • Source Serif Pro - passt sehr gut bei Drucksachen.

Dass Adobe selber auch im Rahmen von Open@Adobe Teile ihrer Entwicklung als Open-Source-Software veröffentlichen war mir neu. Eine Übersicht findet sich auf der Projekt-Seite.

GFA Basic ...

Ich bin gerade per Zufall auf der Wikipediaseite von GFA Basic gelandet.

Das ist die Programmiersprache, mit der ich auf dem Atari ST gearbeitet habe und die ich aus einigen Gründen echt vermisse.

Der Basic-Dialekt war Pascal-ähnlich, also nichts mit Zeilennummern.

Die "IDE" bestand aus einem Editor, der Syntax-Vervollständigung und automatische Einrückung beherrscht hat und per Tastendruck die Basic-Programme auch ausgeführt hat. Später kam noch ein Compiler dazu.

Gerade diese Art von IDE hatte es in sich und es machte richtig Spass, damit zu programmieren.