IOException.de

Icon

Ausgewählter Nerdkram von Informatikstudenten der Uni Ulm

Today I learned: vi-mode in der shell UND in fast allen Kommandozeilen-Tools

Ich bin ein großer Fan des Text-Editors vi. Wenn auch nicht ganz einfach zu erlernen, ermöglicht er es einem – sobald man sich ein wenig damit auskennt – sehr effizient Texte zu editieren. Die meisten Shells bieten die Möglichkeit eines vi-mode (mit dem Befehl set -o vi). In diesem Modus lässt sich die Kommandozeile mit vi-Tasten bedienen, was das arbeiten damit nochmals deutlich effizienter macht. Mein Problem bisher lag darin, dass der vi-mode nicht funktioniert hat, sobald ich ein anderes interaktives Kommandozeilen-Tool in der Shell öffnete (z.B. sftp). Neulich kam jedoch ein Freund zu mir und sagte: “Doch! Das geht!”
Hier ist die Lösung. Man legt eine Datei ~/.inputrc mit folgendem Inhalt an:
set keymap vi
set editing-mode vi

…und schon funktionieren die vi keybindings in nahezu allen Kommandozeilen-Tools :D

tmux ohne root-Rechte installieren

Ich bin seit langer Zeit begeisteter Nutzer von tmux. Tmux ist ein Terminal Multiplexer (wie auch GNU Screen). Das bedeutet, dass man mit tmux mehrere (oder auch sehr viele oder auch nur eine) Shells in einem einzigen Terminal haben kann, was in sehr sehr vielen Fällen unheimlich praktisch ist. Ich verwende tmux unter anderem für folgende Zwecke:

  • Um mehrere (Kommandozeilen-)Programme gleichzeitig sehen zu können. Früher habe ich dafür einfach das Terminal-Programm mehrfach geöffnet. Das hat auch seine Berechtigung, wenn man z.B. seine Window-Manager-Funktionen nutzen möchte, um zwischen den Terminals zu wechseln. Auf Dauer hat sich hier tmux aber als praktischer herausgestellt. Unter anderem auch wegen des folgenden Punkts:
  • Um Text in der selben Shell oder zwischen verschiedenen Shells kopieren und einfügen zu können (Copy & Paste). Tmux bietet hierfür wunderbare Unterstützung.
  • Um in einer Shell zurück-scrollen zu können. Klar, fast alle Terminal-Programme können das auch. Aber mit tmux kann ich dann auch gleich noch Text kopieren. Und es funktioniert auch in Terminals, die nicht auf einer grafischen Oberfläche laufen.
  • Um meine laufenden Prozesse nicht zu verlieren, wenn aus irgendwelchen Gründen das Terminal geschlossen wird. Wenn ich mich z.B. auf einem Server per SSH anmelde, dann starte ich zuallererst einen tmux. Wenn jetzt die Internetverbindung abbricht, dann läuft der tmux auf dem Server weiter und ich kann mich einfach neu verbinden. Das Gleiche gilt natürlich, wenn man versehentlich sein grafisches Terminal schließt, oder X11 abstürzt.

Das alles sind eher Kleinigkeiten, die sich aber in der täglichen Arbeit als ungeheuer wertvoll herausstellen. Ich wüsste gar nicht mehr, wie ich ohne meinen tmux klar kommen sollte.

Jetzt ist tmux nicht unbedingt auf allen Rechnern, mit denen man so zu tun hat, verfügbar. Die Rechner des Linux-Pools der Uni-Ulm haben zum Beispiel keinen tmux installiert. Da ich aber unbedingt einen haben wollte, habe ich mich entschieden, diesen einfach selber zu kompilieren. Das ist nicht ganz trivial, da tmux einige Abhängigkeiten hat. Während meiner Recherche bin ich dann auf ein Skript gestoßen, welches tmux lokal installiert, sodass man keine root-Rechte benötigt. Vielen Dank an den Autor für diese Hilfe! Ich habe das Skript nicht komplett ausgeführt, sondern einzelne Befehle davon verändert angewandt, da ich einige der Schritte darin schon selbst erledigt hatte. Man kann es also auch wunderbar als Nachschlagewerk verwenden.

Damit war’s das auch für heute.
Bis bald,
Matou

Simple cURL based activity monitor for websites

I wrote a simple activity monitor to notify me about changes on certain websites. The script is executed as a cronjob on a dedicated server and regularly fetches certain URIs. It then executes diff on the last file fetched from this URI. If there is a difference, it is mailed to me. To describe some use cases:

  • Product in Online-Shop is out of stock, I want to be notified when it is available again.
  • University lecture. Want to be notified when news/exercises/etc are put on the lecture website.
  • Usenet Search. Want to be notified when certain files are available and can be found via a Usenet search site.
  • Event registration. I monitored a Barcamp website to get notified, once the registration was available.
  • Monitor changes on certain Wiki pages.
  • Regularly check if something can be ordered now.
  • Monitor changes to a certain Etherpad instance.
  • Monitor changes on databases. Some projects offer a HTTP API (e.g. OpenStreetMap). Regularly exporting the database file and running diffs against it shows changes.
  • Monitor newly created mailinglists via the lists interface offered by our university.
  • Monitor the delivery status of packages, by fetching the transport providers tracking page.

Generally the idea is simply to monitor content changes on HTTP resources and thus the script can easily be used for anything that supports HTTP. A simple monitor is set-up like this:
./check-for-changes.sh "alice@mail.de" "http://some-resource.net/"

If you want to monitor only a certain part of a website you can use a preprocess file to filter out content you don’t want to monitor:
./check-for-changes.sh "alice@mail.de" "http://some-resource.net/" "./preprocess/only-body.sh"

I have released the project under a MIT license via GitHub.
differenziert.net: Plattform zur Meinungsbildung

Ein graphisches Frontend für traceroute

Um mich näher mit Processing und OpenGL auseinanderzusetzen habe ich ein Frontend für das Unix Programm traceroute geschrieben. Die Ausgabe von traceroute ist eine Liste mit Stationen die ein Paket auf seinem Weg durch das Netzwerk passiert. Dies kann etwa für das Debuggen einer Netzwerkverbindung genutzt werden.

Technisch wird dies über das “Time-To-Live”-Feld im Header von IP-Paketen realisiert. Der TTL-Eintrag gibt an, nach wie vielen Stationen ein Paket verworfen werden soll. Jeder Router, den das Paket passiert, dekrementiert dieses Feld. Ist die TTL bei 0 angelangt wird das Paket verworfen und der Absender mittels einer ICMP-Nachricht TIME_EXCEEDED benachrichtigt.

traceroute macht sich diesen Umstand zunutze indem immer wieder Pakete an den Zielhost gesendet werden. Die TTL wird dabei schrittweise erhöht bis das Ziel erreicht ist. Die Hosts auf dem Weg werden sich nach und nach mit ICMP-Nachrichten melden, so dass wir dann Informationen über den Absender gewinnen und somit (hoffentlich) die einzelnen Stationen auf unserer Route identifizieren können. Diese Route muss hierbei nicht zwangsläufig korrekt sein. Es können sich aus verschiedenen Gründen Abweichungen ergeben, etwa durch Firewalls die aus Sicherheitsgründen ICMP gleich komplett deaktivieren.

Für die Visualisierung habe ich traceroute, wie im letzten Beitrag beschrieben, als externes Programm an Processing angebunden. Das Frontend liest dabei die Ausgabe des Kommandoaufrufs traceroute domain.org bis EOF. Jede Zeile wird geparsed, dabei werden die einzelnen Hosts der Route nach IP-Adressen aufgelöst und anschließend die Koordinate bestimmt. Die Koordinaten können anschließend mit etwas sin/cos Grübeln auf einer Erdkugel abgebildet werden. Das Auflösen nach Geolocations habe ich mittels einer GeoIP-Datenbank realisiert. GeoIP-Datenbanken stellen eine Zuordnung IP zu Koordinate dar. Natürlich nur mit einer bestimmten Wahrscheinlichkeit und auch nicht völlig exakt, aber für unsere Zwecke reicht das. Es gibt hier einige freie und natürlich jede Menge kommerzielle Anbieter. Ich habe mich dabei für die freie GeoLite City von Maxmind entschieden. Im Endeffekt löse ich so jetzt eine IP-Adresse zu einer WGS84-Koordinate auf.

Für das Frontend habe ich in Java mithilfe der Processing API eine Visualisierung geschrieben. Die Textur der Weltkugel wird mittels eines in GLSL geschriebenen Shaders weiter verändert. Bibliotheken, die ich verwendet habe: GLGraphics (OpenGL Rendering Engine für Processing), controlP5 (Button, Slider, Textfield) und toxiclibs (Interpolation & andere numerische Methoden).

Den Sourcecode habe ich unter MIT auf GitHub veröffentlicht: visual-traceroute.

Ein bisschen Eye Candy gibts in dem Video unter diesem Beitrag bzw. hier als Direktlink auf Vimeo.

Die UNIX-Philosophie

Das UNIX-Betriebssystem wurde in den sechziger Jahren von Bell Laboratories entwickelt. Ein Großteil der heute populären Betriebssysteme wie GNU/Linux oder Mac OS X verwenden grundlegende Konzepte, die aus dem ursprünglichen UNIX-Betriebssystem stammen. Die BSD Familie oder Solaris sind direkte UNIX-Nachfolger. Man bezeichnet diese Systeme daher als unixoide Betriebssysteme. Es ist kein Zufall, dass die effizientesten, sichersten und fortschrittlichsten Betriebssysteme UNIX-Derivate sind. Unix-Systeme sind ideal für die Zukunft gerüstet, da sie die Grundannahme haben, dass sich alles ständig ändert. Der Aufbau ist deshalb äußerst flexibel gehalten.

Mit der Unix-Philosophie bezeichnet man die Konzepte, die beim Erstellen des ursprünglichen Unix-Systems von den Entwicklern angewandt wurden. UNIX wurde als System für Experten entworfen. Für Leute, die wissen was sie tun und was sie wollen. Auf Einsteigerfreundlichkeit wurde keinen Wert gelegt. Die Benutzerschnittstelle zur Interaktion mit dem Betriebssystem ist die Shell.

Es gibt einige Konzepte, die allgemein unter die Unix-Philosophie fallen. Ich möchte in diesem Beitrag einige der wichtigsten herausgreifen um einen Einblick zu geben.

UNIX-Typografie

Make each program do one thing well.
Anstatt ein großes monolithisches Programm zu entwickeln sollte ein Programm genau eine Sache tun — und das richtig! Ein solches Programm hat viele Vorteile:

Programme die genau eine Sache tun können speziell für diese Aufgabe konzipiert werden.

Viele einzelne Programme, die genau eine Sache machen, können sehr einfach kombiniert werden! Aus der Kombination von vielen einzelnen Dingen ergibt sich leicht etwas neues, viel größeres. Wie in einem Werkzeugkasten ist es sehr einfach sich die richtigen Programme für eine Aufgabe zu suchen und diese passend zu kombinieren. All das ermöglicht einen hohen Grad an Abstraktion, der es ermöglicht sehr schnell und effizient ein Ziel zu erreichen.

Um etwa herauszufinden, wie viele verschiedene Dateien in einem Verzeichnis liegen und welchen Typ diese haben können folgende Kommandos in der Shell kombiniert werden: file -b * | sort | uniq -c.
Pipes | sind ein effizientes Konzept um die Programmausgabe direkt als Eingabe an ein anderes Programm weiterzuleiten. Das Programm, an das weitergeleitet wird, beginnt mit der Verarbeitung sobald eine Eingabe vorliegt.
Summiert man die Quelltexte der einzelnen Programme auf kommt man auf mehrere tausend Zeilen Quelltext, die in dieser einen Zeile verwendet werden. Jedes dieser Programme wurde für genau eine Aufgabe entworfen, über Jahre konstant verbessert, ausgebessert und angepasst.

Bei unixoiden Systemen zieht sich dieser Aufbau durch, so sind viele Benutzeroberflächen oft einfach nur grafische Frontends für Kommandozeilentools (diskutil/Festplattendienstprogramm unter Mac OS X oder tcpdump/Wireshark etwa).

Small programs are beautiful.
Programme sollten klein sein. Das macht es einfach sie zu entwickeln, zu pflegen und zu verstehen. Für neue Entwickler ist es leichter sich in das Programm einzuarbeiten, die Funktionalität des Quelltextes ist überschaubar. Die Komplexität eines Programms wird so klein gehalten. Es fällt leichter Fehler zu finden und zu beheben.

Ein weiterer Vorteil ist, dass kleine Programme ressourcenschonend sind: Sie können vom Betriebssystem schnell geladen werden, swapping und paging sind seltener nötig. Im Endeffekt ergibt sich so ein schnelleres Gesamtsystem.

Wie aber legt man fest was ein “kleines” Programm ist? Mike Gancarz gibt in seinem Buch “The UNIX Philosophy” einige Anhaltspunkte: Funktionsdeklarationen, die aufgrund von vielen Parametern umgebrochen werden müssen oder auftretende Probleme, die nicht mehr augenblicklich einem Kontext zugeordnet werden können sind Warnsignale. Strikt der Unix-Philosophie folgend sollte ls keinen Flag zur Formatierung oder Sortierung der Ausgabe haben — hierfür gibt es andere Programme (column, sort, …).

Dieser Aufbau von vielen verschiedene kleinen Programmen die zusammenarbeiten, lässt sich dem Konzept “Divide & Conquer” zuordnen: Dadurch, dass große, komplexe Probleme in einfachere, kleine zerlegt werden wird es einfach diese einzeln zu lösen.

Avoid captive user interfaces.
Programme sollten so geschrieben sein, dass sie problemlos in einem Skript verwendet werden können. Die Schnittstelle muss für Maschinen entworfen sein — nicht für Menschen. Das bedeutet beispielsweise, dass Programme nach dem Aufruf nicht noch auf Benutzereingaben angewiesen sein sollten (“Sind Sie sicher, dass Sie …? y/n”), sondern nur über die Kanäle STDIN, STDOUT & STDERR kommunizieren sollten.
Das macht Automatisierung einfacher, es ist sehr einfach Programme miteinander zu verknüpfen, die eben nicht irgendwann auf eine Benutzereingabe warten und deswegen blocken. Das UNIX-Konzept macht es sehr einfach, Programme zu kombinieren.

Zum Vergleich: Befehle wie dir erzeugen unter Windows-Systemen auf ein leeres Verzeichnis angewandt eine Ausgabe mit mehreren Zeilen — ohne relevanten Informationen. Diese Ausgabe weiterzuverarbeiten oder zu parsen ist nicht ohne weiteres machbar. Programme, die strikt der Unix-Philosophie folgen verhalten sich dagegen nach dem Grundsatz “Silence is golden”.

Build a prototype as soon as possible.
In der Unix-Philosophie nehmen Prototypen eine zentrale Rolle ein. Die Sichtweise ist hier, dass viele traditionelle Softwareentwicklungsprozesse durch Anforderungsanalyse, Spezifikationen, etc. darauf abzielen von Anfang an das ideale System zu den Anforderungen zu bauen. Oder anders ausgedrückt: Beim ersten Mal alles richtig zu machen.

Die Sichtweise der Unix-Philosophie ist hier, dass sich ein solches System nie in einem Zyklus bauen lässt. Systeme müssen verschiedene Phasen durchlaufen und konstant, iterativ verbessert werden um Anforderungen ideal zu erfüllen. In jeder Phase muss dazu gelernt werden. Die Alternative ist einen Prototypen zu bauen und diesen iterativ auszubauen. Da Programme klein und überschaubar sein sollen fällt der Prototypenbau leichter.

Automate everything
Aufgaben, die heute von Hand ausgeführt werden, obwohl sie auch das System übernehmen könnte, sind nüchtern betrachtet Zeitsverschwendung. Da unter unixoiden Systemen Programme darauf ausgelegt sind mit anderen Programmen zu interagieren — und nicht mit Menschen, können Abläufe beispielsweise mittels Shellskripten einfach automatisiert werden. In Shellskripten können Programme und Kommandos wie Funktionen verwendet werden. Die Ausgabe kann direkt in den Programmfluss integriert weren.

Fazit
Die wichtigsten Konzepte zusammengefasst: Dinge einfach halten, Komplexität vermeiden. Eine Sache richtig machen. Programme miteinander kombinieren.

Das war jetzt lediglich ein kleiner Einblick in die Unix-Philosophie. Es gibt noch deutlich mehr Konzepte und man kann die Ideen auch nicht nur auf Betriebssysteme anwenden. Für weitere Informationen kann ich folgende Quellen sehr empfehlen:

Natürlich gibt es auch Probleme eines solchen Systemaufbaus. Diese habe ich hier absichtlich nicht thematisiert. Wer sich hierfür interessiert sollte sich etwa zu Plan 9 oder Kernelproblemen informieren.

ioexception.de

Benjamin Erb [] studiert seit 2006 Medieninformatik und interessiert sich insbesondere für Java, Web-Technologien, Ubiquitous Computing, Cloud Computing, verteilte Systeme und Informationsdesign.


Raimar Wagner studiert seit 2005 Informatik mit Anwendungsfach Medizin und interessiert sich für C++ stl, boost & Qt Programmierung, Scientific Visualization, Computer Vision und parallele Rechenkonzepte.


David Langer studiert seit 2006 Medieninformatik und interessiert sich für Web-Entwicklung, jQuery, Business Process Management und Java.


Sebastian Schimmel studiert seit 2006 Informatik mit Anwendungsfach Medizin und interessiert sich für hardwarenahe Aspekte, Robotik, webOs, C/C++ und UNIX/Linux.


Timo Müller studiert seit 2006 Medieninformatik. Er interessiert sich allen voran für Mobile and Ubiquitous Computing, systemnahe Enwticklung und verteilte Systeme, sowie Computer Vision.


Achim Strauß studiert seit 2006 Medieninformatik. Seine Interessen liegen in Themen der Mensch-Computer Interaktion sowie Webentwicklung und UNIX/Linux.


Tobias Schlecht studiert seit 2006 Medieninformatik und interessiert sich vor allem für Software Engineering, Model Driven Architecture, Requirements Engineering, Usability Engineering, Web-Technologien, UML2 und Java.


Fabian Groh studiert seit 2006 Medieninformatik. Seine Interessengebiete sind Computer Graphics, Computer Vision, Computational Photography sowie Ubiquitos Computing.


Matthias Matousek studiert seit 2007 Medieninformatik und interessiert sich besonders für Skriptsprachen, Echtzeitsysteme und Kommunikation.


Michael Müller [] studiert seit 2009 Medieninformatik. Er interessiert sich vor allem für Web-Technologien, Ubiquitous Computing, User-Interfaces, UNIX und Creative Coding.


Falco Nogatz [] studiert seit 2010 Informatik mit Anwendungsfach Mathematik. Er interessiert sich für Web-Technologien, Programmierparadigmen und theoretische Grundlagen.

Archiv

Februar 2015
M D M D F S S
« Mrz    
 1
2345678
9101112131415
16171819202122
232425262728