Whois Plugin für den zBot

10. Juli 2009 von zimon

Vor einiger Zeit habe ich ein Whois-Plugin für meinen Jabber Bot zBot geschrieben. Aus irgendeinem Grund habe ich es nie online gestellt. Dies möchte ich hiermit nachholen. Ich habe den Code noch ein wenig verschönert.

Fauchi95 hat mich gefragt, ob man nicht ein Whois-Plugin schreiben könnte, da ist es mir wieder eingefallen :-)

Die Bedienung ist so wie man es sich denkt. Man sendet dem Bot ein whois gefolgt von der gewünschten Domain und bekommt das Ergebnis zurück gesendet.

Beispiel:

whois zinformatik.de

Zum Installieren des Plugins kopiert man die Datei Whois.pm in das Verzeichnis plugins im Hauptverzeichnis des zBot und startet dann den Bot neu.

Download:
Whois.pm

VNUML – Ein Netzwerksimulator mit User-Mode-Linux

27. Juni 2009 von zimon

Foto: Ben Stanfield

Foto: Ben Stanfield

VNUML (Virtual Network User-Mode-Linux) ist ein Programm um Netzwerke zu simulieren. Dabei werden die beteiligten Rechner nicht nur simuliert, sondern als virtuelle Maschinen gestartet, wodurch sie mit echten Protokollen miteinander kommunizieren. Daher eignet sich dieses Tool sehr gut zum Testen und Lernen z.B von Routingprotokollen. Man kann damit jedoch auch Paketfiltering mittels iptables sowie andere Dienste wie ARP, DNS oder ICMP ausprobieren. Auch eigene Entwicklungen können so getestet werden.
Da für jeden Rechner ein User-Mode-Linux System (englisch) – welches über einen echten Kernel und ein eigenes Dateisystem verfügt – gestartet wird, ist die Simulation sehr realitätsnah und die Rechner verhalten sich wie echte autonome Maschinen.
Für diesen Artikel ist es vorteilhaft, wenn man grundlegende Kenntnisse über Netzwerke besitzt (es wird z.B. vorausgesetzt, dass man weiß was IP-Adressen, Netze und Netzmasken sowie Router sind)

UPDATE: Artikel nochmal überarbeitet

Installation
Für Debian basierte Distributionen gibt es ein .deb Paket, welches zumindest unter Ubuntu problemlos installiert werden kann. Ansonsten kann man sich den Quelltext herunter laden. Eine englische Installationsanleitung ist auch verfügbar.
Ist VNUML installiert, braucht man noch ein Dateisystem. Auf der Projektseite gibt es 2 verschiedene zum downloaden. Ein größeres, welches mehr Programme beinhaltet und ein sehr abgespecktes, welches nützlich ist um größere Netzwerke zu generieren, da für jeden virtuellen Rechner ein Dateisystem im Arbeitsspeicher liegt.
Man kopiert das gewählte Dateisystem nach /usr/share/vnuml/filesystems/filesystem.img. Für die Beispiele in diesem Artikel reicht das kleine, welches man als mini_fs speichern kann. Dafür können die folgenden Befehle benutzt werden, nachdem man die Datei n3vlr-0.11-vnuml-v0.1.tar.gz herunter geladen hat:

tar -xvzf n3vlr-0.11-vnuml-v0.1.tar.gz
sudo cp n3vlr-0.11-vnuml-v0.1.img /usr/share/vnuml/filesystems/mini_fs

Möchte man das Dateisystem ändern um z.B. neue Programme hinzuzufügen oder unbenötigte Dateien zu löschen, kann man dieses mit dem Befehl

sudo mkdir /mnt/vnuml
sudo mount -o loop /usr/share/vnuml/filesystems/filesystem.img /mnt/vnuml

einhängen. Nun kann man im Ordner /mnt/vnunml alle gewünschten Änderungen vornehmen und das Dateisystem danach mit sudo umount /mnt/vnuml wieder aushängen.

Scenariodatei erstellen
Die Netzwerktopologie wird in einer XML-Datei beschrieben. In dieser werden zuerst die globalen Einstellungen festgelegt, in denen unter anderem angegeben wird, wo das zu nutzende Dateisystem liegt und welchen ssh-Key man nutzen möchte um auf die virtuellen Rechner zuzugreifen.
Danach folgen die Definitionen der Netze gefolgt von den Rechnern.
Im folgenden eine minimale Beispielkonfiguration, die zwei Rechner beschreibt, die über ein Netz miteinander verbunden sind. Zuerst der globale Teil, in dem die VNUML-Version, der Name des Scenarios und weitere Einstellungen definiert werden. Dort wird auch das Management-Netz (192.168.0.0/24) definiert, über das man vom eigenen Rechner auf die verschiedenen virtualisierten Maschinen zugreifen kann.
Existiert noch kein öffentlicher ssh-key, so sollte man sich mit folgendem Kommando einen anlegen:

sudo ssh-keygen

Bei der Frage nach einem Passwort drückt man einfach Enter ohne ein Passwort einzugeben. Der vorgeschlagene Pfad sollte stimmen, kann also beibehalten werden.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vnuml SYSTEM "/usr/share/xml/vnuml/vnuml.dtd">
 
<vnuml>
    <global>
        <version>1.8</version>
        <simulation_name>beispiel</simulation_name>
        <ssh_version>2</ssh_version>
        <ssh_key>/root/.ssh/id_rsa.pub</ssh_key>
        <automac/>
        <vm_mgmt type="private" network="192.168.0.0" mask="24" offset="100" >
            <host_mapping/>
        </vm_mgmt>
        <vm_defaults exec_mode="mconsole">
            <filesystem type="cow">/usr/share/vnuml/filesystems/mini_fs</filesystem>
            <kernel>/usr/share/vnuml/kernels/linux</kernel>
        </vm_defaults>
    </global>

Als nächstes werden die Netze definiert. In diesem Beispiel gibt es nur ein Netz, da man sich sonst um das Routing kümmern müsste (dazu später mehr).

    <net name="net1" mode="virtual_bridge"/>

Im Modus “virtual_bridge” werden die Interfaces aller virtuellen Rechner sowie alle Netze über Bridges ans Hostsystem (den eigenen Rechner) gekoppelt, so dass man sie mit einem ifconfig sehen und mittels tcpdump oder Wireshark überwachen kann. Dafür wird jedoch das Paket “bridge-utils” benötigt. Alternativ kann man statt dessen auch “uml_switch” benutzen.

Nun folgen die Definitionen der virtuellen Rechner. Bei beiden Rechnern wird ein Interface definiert (es können aber auch mehrere sein, z.B. für Router).

    <vm name="rechner1">
        <if id="1" net="net1">
            <ipv4 mask="255.255.255.0">10.0.1.1</ipv4>
        </if>
    </vm>
 
    <vm name="r2">
        <if id="1" net="net1">
            <ipv4 mask="255.255.255.0">10.0.1.2</ipv4>
        </if>
    </vm>
</vnuml>

Es empfiehlt sich die Datei genauso wie das Scenario (die globale Eigenschaft simulation_name) zu benennen. In diesem Fall also beispiel.xml

Scenario starten und zu den Rechnern verbinden
Um das Scenario zu starten genügt der folgende Aufruf:

sudo vnumlparser.pl -t beispiel.xml

Nachdem das Scenario gestartet ist, kann man sich auf einen der Rechner einloggen:

sudo ssh rechner1

Durch die Angabe des öffentlichen ssh-Keys sollte es keine Passwortabfrage geben. Ansonsten ist das Passwort per default xxxx. Nun kann man alles mögliche Testen. Man kann einen Ping versenden:

ping 10.0.1.2

oder ein Interface überwachen.
Dafür loggt man sich am besten in einer anderen Konsole auf dem 2. Rechner ein:

sudo ssh rechner2

und startet dort einen TCP-Dump:

tcpdump -i eth1

Der Ping sollte die ganze Zeit weiter laufen, damit man auch etwas sehen kann. Danach kann man ihn mit Strg+c stoppen.
Mit exit kann man einen Rechner wieder verlassen.
Da man häufiger auf mehreren Rechnern gleichzeitig eingeloggt sein möchte wenn man mit VNUML arbeitet, bietet es sich an Screen zu benutzen.
Um die Simulation zu beenden führt man folgenden Befehl aus:

sudo vnumlparser.pl -P beispiel.xml

Dienste starten
Wie bereits erwähnt eignet sich VNUML besonders gut zum ausprobieren und Testen von Routingprotokollen. Daher sind auch die Quagga-Implementationen der bekanntesten Routingprotokolle RIP, OSPF und BGP bereits installiert und können recht einfach genutzt werden. Ich werde in diesem Artikel jedoch nur eine Minimalkonfiguration für RIP und OSPF angeben. Eine Einführung in diese Protokolle und deren Konfiguration würde an dieser Stelle zu weit führen.
Um das Routing grundsätzlich zu aktivieren wird das Tag

<forwarding type="ipv4" />

genutzt. Weitere Tags binden ein Konfigurationsverzeichnis conf ein (welches im gleichen Verzeichnis, wie die xml-Datei des Scenarios liegt) und starten die verschiedenen Daemons.
Im Verzeichnis conf sollten dann die folgenden Dateien vorhanden sein:

zebra.conf

!
hostname zebra
!
password xxxx
enable password xxxx

ripd.conf

!
hostname ripd
password xxxx
!
router rip
network 10.0.0.0/8

ospfd.conf

!
hostname ospfd
password xxxx
!
router ospf
network 10.0.0.0/8 area 0

Weitere Infos zu den Quagga-Routingprotokollen gibt es unter http://www.quagga.net.
Ein Scenario, welches der Einfachheit halber nur aus Routern besteht, auf denen man wahlweise OSPF oder RIP starten kann wird im folgenden Beispiel definiert:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE vnuml SYSTEM "/usr/share/xml/vnuml/vnuml.dtd">
 
<vnuml>
    <global>
        <version>1.8</version>
        <simulation_name>mini</simulation_name>
        <ssh_version>2</ssh_version>
        <ssh_key>/root/.ssh/id_rsa.pub</ssh_key>
        <automac/>
        <vm_mgmt type="private" network="192.168.0.0" mask="24" offset="100" >
            <host_mapping/>
        </vm_mgmt>
        <vm_defaults exec_mode="mconsole">
            <filesystem type="cow">/usr/share/vnuml/filesystems/mini_fs</filesystem>
            <kernel>/usr/share/vnuml/kernels/linux</kernel>
        </vm_defaults>
    </global>
 
    <net name="net1" mode="virtual_bridge"/>
    <net name="net2" mode="virtual_bridge"/>
 
    <vm name="r1">
        <if id="1" net="net1">
            <ipv4 mask="255.255.255.0">10.0.1.1</ipv4>
        </if>
 
        <forwarding type="ipv4" />
 
        <filetree root="/etc/quagga" seq="start">conf</filetree>
        <exec seq="start" type="verbatim">sysctl -w net.ipv4.conf.all.rp_filter=0</exec>
        <exec seq="start" type="verbatim">hostname</exec>
        <exec seq="start" type="verbatim">/usr/lib/quagga/zebra -f /etc/quagga/zebra.conf -d</exec>
        <exec seq="rip" type="verbatim">/usr/lib/quagga/ripd -f /etc/quagga/ripd.conf -d</exec>
        <exec seq="ospf" type="verbatim">/usr/lib/quagga/ospfd -f /etc/quagga/ospfd.conf -d -P 2604</exec>
        <exec seq="stop" type="verbatim">hostname</exec>
        <exec seq="stop" type="verbatim">killall zebra</exec>
        <exec seq="stop" type="verbatim">killall ripd</exec>
        <exec seq="stop" type="verbatim">killall ospfd</exec>
 
        <exec seq="rpfilter" type= "verbatim">
            for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
        </exec>
    </vm>
 
    <vm name="r2">
        <if id="1" net="net1">
            <ipv4 mask="255.255.255.0">10.0.1.2</ipv4>
        </if>
        <if id="2" net="net2">
            <ipv4 mask="255.255.255.0">10.0.2.1</ipv4>
        </if>
 
        <forwarding type="ipv4" />
 
        <filetree root="/etc/quagga" seq="start">conf</filetree>
        <exec seq="start" type="verbatim">sysctl -w net.ipv4.conf.all.rp_filter=0</exec>
        <exec seq="start" type="verbatim">hostname</exec>
        <exec seq="start" type="verbatim">/usr/lib/quagga/zebra -f /etc/quagga/zebra.conf -d</exec>
        <exec seq="rip" type="verbatim">/usr/lib/quagga/ripd -f /etc/quagga/ripd.conf -d</exec>
        <exec seq="ospf" type="verbatim">/usr/lib/quagga/ospfd -f /etc/quagga/ospfd.conf -d -P 2604</exec>
        <exec seq="stop" type="verbatim">hostname</exec>
        <exec seq="stop" type="verbatim">killall zebra</exec>
        <exec seq="stop" type="verbatim">killall ripd</exec>
        <exec seq="stop" type="verbatim">killall ospfd</exec>
 
        <exec seq="rpfilter" type= "verbatim">
            for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
        </exec>
    </vm>
 
    <vm name="r3">
        <if id="1" net="net2">
            <ipv4 mask="255.255.255.0">10.0.2.2</ipv4>
        </if>
 
        <forwarding type="ipv4" />
 
        <filetree root="/etc/quagga" seq="start">conf</filetree>
        <exec seq="start" type="verbatim">sysctl -w net.ipv4.conf.all.rp_filter=0</exec>
        <exec seq="start" type="verbatim">hostname</exec>
        <exec seq="start" type="verbatim">/usr/lib/quagga/zebra -f /etc/quagga/zebra.conf -d</exec>
        <exec seq="rip" type="verbatim">/usr/lib/quagga/ripd -f /etc/quagga/ripd.conf -d</exec>
        <exec seq="ospf" type="verbatim">/usr/lib/quagga/ospfd -f /etc/quagga/ospfd.conf -d -P 2604</exec>
        <exec seq="stop" type="verbatim">hostname</exec>
        <exec seq="stop" type="verbatim">killall zebra</exec>
        <exec seq="stop" type="verbatim">killall ripd</exec>
        <exec seq="stop" type="verbatim">killall ospfd</exec>
 
        <exec seq="rpfilter" type= "verbatim">
            for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
        </exec>
    </vm>
</vnuml>

Die Topologie des Beispielscenarios mini.xml

Die Topologie des Beispielscenarios mini.xml

Dieses Beispiel besteht aus 3 Routern, die mit zwei Netzen zu einer “Kette” verbunden sind (siehe Abbildung rechts). Startet man dieses Scenario, so kann man nicht von r1 (10.0.1.1) nach r3 (10.0.2.2) pingen, da die Routingdaemons noch nicht gestartet sind und r1 noch nichts von net2 weiß:

sudo vnumlparser.pl -t mini.xml
sudo ssh root@r1
ping 10.0.2.2

Wie man sieht, kommen die Pings nicht bei r3 an. Mit exit verläst man den Router r1 wieder.
Es gibt nun 4 Sequenzen, die ausgeführt werden können: start, stop, rip und ospf. Dabei wird durch ausführen der Sequenz start der Hostname gesetzt und der zebra-Daemon gestartet. Mit rip oder ospf wird der entsprechende Routingdaemon gestartet und stop beendet alle Routingprozesse.
Man startet nun also z.B. den RIP-Daemon mit den folgenden Befehlen:

sudo vnumlparser.pl -x start@mini.xml
sudo vnumlparser.pl -x rip@mini.xml

Nun kann man testen, ob das Routing auch funktioniert, indem man den Ping, der vorher fehlschlug wiederholt:

sudo ssh root@r1
ping 10.0.2.2

Jetzt sollte der Ping funktionierten. Bei größeren Scenarien kann es einige Sekunden dauern bis alle Router über die notwendigen Informationen verfügen (also bis das Scenario konvergent ist).

Natürlich gibt es noch viele weitere Optionen und Möglichkeiten, die VNUML zur Verfügung stellt. Dies soll nur eine kleine Einführung sein, um die ersten Schritte mit diesem System zu machen.

Links

Vim Plugin – Tasklist sammelt Infos über offene und fertige Todos

23. Juni 2009 von zimon

Das Vim Plugin Tasklist ist ein kleines aber praktisches Plugin, welches im aktuellen Text nach den Wörtern TODO, XXX, FIXME und DONE sucht und eine Liste daraus erstellt.

Sobald das Plugin installiert ist (indem die Datei tasklist.vim nach ~/.vim/plugin/ kopiert wurde), kann man die TODO-Liste mit \t generieren und angezeigen.

Dabei öffnet sich ein horizontaler Splitscreen, in dem alle Vorkommen von TODO, XXX und FIXME sortiert nach Vorkommen und mit Angabe der Zeilennummer aufgeführt werden. Dabei wird auch der Rest der Zeile hinter dem Schlüsselwort angezeigt, so dass man auch sehen kann worum es bei einem TODO geht.

Wenn man mit j und k durch die Liste navigiert wird die entsprechende Textstelle im eigentlichen Text jeweils automatisch angesprungen. Drückt man Enter, so schließt sich der Splitscreen und man befindet sich an der Stelle des zuletzt ausgewählten TODOs im Text.

Die mit DONE gekennzeichneten Textstellen werden unter den noch offenen TODOs angezeigt. Ansonsten funktionieren sie genauso wie TODOs.

Nach jedem Speichervorgang kann die Liste mit \t neu generiert werden.

POV-Ray – ein Raytracer

21. Juni 2009 von zimon
Ein mit POV-Ray generiertes Bild

Ein mit POV-Ray generiertes Bild

Mit dem quelloffnen Raytracer POV-Ray kann man sehr realitätsnahe Bilder erzeugen. Anders als bei den meisten anderen 3D-Grafikprogrammen arbeitet man hier nicht mit einer graphischen Oberfläche und Maus sondern beschreibt die Objekte textbasiert über dessen Positionen in einem Koordinatensystem.

[UPDATE]Artikel nochmals überarbeitet und Beispiel hinzugefügt.[/UPDATE]

Was ist Raytracing?
Raytracing ist eine Methode um Computergenerierte Bilder zu erzeugen. Der Unterschied zum Rendering besteht darin, dass keine Gittermodelle mit Texturen belegt werden und die Farbe dann mittels des Lichtes berechnet wird sondern eine Strahlenverfolgung statt findet, wodurch viel realistischere Bilder entstehen. Leider ist dieses Verfahren auch wesentlich rechenintensiver. Dafür bekommt man Schatten und Spiegelungen quasi geschenkt, was mit Rendering relativ schwer zu realisieren ist. (Siehe auch: http://de.wikipedia.org/wiki/Raytracing)

Einen guten Eindruck, was POV-Ray leisten kann bekommt man in der Galerie der POV-Ray Homepage.

Download und Installation
POV-Ray steht unter einer eigenen Lizenz, die zwar das Einsehen des Quelltextes, aber nicht die veränderte Weitergabe im Sinne freier Software erlaubt (was sich aber bald ändern soll, siehe Kommentare).

Das Programm ist für alle gängigen Betriebssysteme verfügbar und kann sogar in einem Cluster (also auf mehreren PC’s gleichzeitig) verwendet werden.
[UPDATE]POV-Ray kann unter Ubuntu mittels sudo apt-get install povray installiert werden.
Ansonsten kann man die Binärdateien von der Homepage beziehen[/UPDATE]

Grundsätzliche Funktionsweise
In einer Scenenbeschreibungssprache werden alle Objekte, Lichtquellen und die Kamera an 3D-Positionen im Raum definiert (z.B. Kugel an Stelle x,y,z mit Radius r und Farbe rot). Daneben gibt es noch viele weitere Optionen um bestimmte Materialien zu simulieren. Daraus wird dann das Bild berechnet.

Zitat:

Der Qualität und dem Anspruch der gerenderten Bilder sind keine theoretischen Grenzen gesetzt;
in der Praxis ist die zur Verfügung stehende Rechen- oder Computer-Zeit der begrenzende Faktor.

Quelle: http://de.wikipedia.org/wiki/Povray

Interessant ist Povray durch seine Scenenbeschreibungssprache auch wegen der Automatisierbarkeit.
z.B. ist EAGLE ein Programm um elektronische Schaltungen zu entwerfen und daraus entsprechende Boardlayouts zu konstruieren. Mittels eines Scripts kann man sich die Platine zu einem fertigen Layout vor dem eigentlichen Bau mit POV-Ray Rendern lassen um sich ansehen zu können, wie es später aussehen wird. (Macht sich sehr gut in Ausarbeitungen oder um vorab etwas präsentieren zu können.)

Das Board-Layout eines USB<->UART Konverters

Das Board-Layout eines USB<->UART Konverters

Das mit POV-Ray aus dem Board-Layout generierte Bild

Das mit POV-Ray aus dem Board-Layout generierte Bild

Ein Foto der fertigen Platine

Ein Foto der fertigen Platine (um 180° gedreht)

Übrigens ist der linke Teil meines Banners (oben auf der Seite) auch ein Teil einer mit POV-Ray gerenderten Platine. Der Rechte Teil ist ein Ausschnitt des EALGE Layouts, aus dem es generiert wurde.

Beispiel
Im folgenden Beispiel wird eine einfache Scene erstellt. Zuerst wird eine Datei mit Farbdefinitionen eingebunden, damit man nicht jede Farbe als RGB-Wert eingeben braucht. Danach wird eine Kamera definiert. Dabei gibt man die Position an, wo sie sich befinden soll und die Position, auf die die Kamera zeigen soll.
Als nächstes muss noch eine Lichtquelle definiert werden, damit man auch etwas sehen kann. Diese wird mit dem Schlüsselwort light_source eingeleitet und hat eine Position und eine Farbe. Nun können die einzelnen Objekte definiert werden.
Als Boden wird eine Ebene definiert, die schwarz-weiß kariert ist und waagerecht auf der Höhe -1 liegt. Die Koordinaten geben die Lage der Ebene an, die immer Senkrecht auf dem angegebenen Vektor liegt. Dahinter kann man ein Offset (der Abstand zum Nullpunkt), in diesem Fall also die Höhe angeben.
Die Farbe wird mit dem Schlüsselwort “pigment” angegeben. Da die Ebene Kariert sein soll nutzen wir hier die Option “checker” gefolgt von zwei Farbwerten.
Durch die Include-Anweisung am Anfang können hier die Namen der Farben verwendet werden. Ansonsten müsste man den RGB-Wert angeben.
Der Himmel wird durch ein “sky_sphere”-Objekt erzeugt, welches entlang der y-Achse (“gradient y”) von Hellblau nach Blau verläuft (“color_map”).
Nun kann man noch weitere Objekte auf der Ebene platzieren. Eine Kugel (sphere) besitzt einen Mittelpunkt und eine Durchmesser und natürlich auch eine Farbe.
Ein Kegel (cone) hat zwei Koordinaten, die den Mittelpunkte der beiden Enden entsprechen sowie je einen Durchmesser an jedem Ende.

Neben der Farbe kann auch noch die Oberflächenstruktur und -Politur definiert werden. Für die Struktur ist das Schlüsselwort “normal” zuständig, die Politur wird mittels “finish” angegeben. Im Beispiel wird der 2. Kugel eine reflektierende Politur gegeben, so dass sie die anderen Objekte spiegelt. (je höher der Reflektionswert, desto stärker die Spiegelung.

Nun der Code des Beispiels:

#include "colors.inc"
 
camera {    // Die Kamera
    location <2, 3, -6>
    look_at <0, 1, 2>
}
 
light_source { // Die Lichtquelle
    <3, 5, -4>
    color White
}
 
plane { // Eine Ebene
    <0, 1, 0>, -1
    pigment { checker color White, color Black }
} 
 
sky_sphere { // Der Himmel
    pigment {
        gradient y
        color_map { [0.0 color rgb <0.7,0.7,1.0>] [1.0 color blue 0.5] }
    }
}
 
sphere { // eine Kugel
    <-3, 1, 4>, 2
    pigment { color Yellow }
}  
 
cone{   // Ein Kegel
    <3,-1,3>,1,<2.5,4,4>,0
    pigment{color Green}
}
 
sphere { // Eine reflektierende Kugel
    <0, 2.5, 10>, 3
    finish{
        reflection {
            0.8       
        }
    }
}
Das Ergebnis des Beispiels

Das Ergebnis des Beispiels

Sonstige Funktionen
POV-Ray kennt noch eine ganze Menge weiterer Objekte, die sich auch zusammenfassen lassen. Man kann auch – wie in der Mengenlehre – ein Objekt von einem anderen abziehen oder die Schnittmenge zweier Objekte berechnen (und anzeigen).
Auch bei den Farben und Oberflächenstrukturen bzw. -Polituren gibt es noch viele weitere Möglichkeiten und Optionen.

Die Objekte können skaliert (in der Größe geändert) rotiert und translatiert (verschoben) werden.
Es können auch Kontrollstrukturen wie bei Programmiersprachen genutzt werden. So kann man Variablen deklarieren, Schleifen und Verzweigungen nutzen sowie Funktionen (bei POV-Ray Makros genannt) definieren um automatisch eine Reihe von Objekten zu erzeugen und zu transformieren.

Man kann mit POV-Ray auch Animationen erstellen. Dafür werden per Script mehrere Bilder erstellt, wobei vor jedem Bild eine Variable verändert wird. Diese kann genutzt werden um die Kamera oder Objekte zu bewegen.
Hier einige Beispiele (auf Youtube gibt es noch jede Menge weitere)

YouTube Preview Image YouTube Preview Image

Links

Vim als Hexeditor – Binärdateien bearbeiten

13. Juni 2009 von zimon

Vim lässt sich selbstverständlich auch als Hexeditor nutzen. Dafür wird (normalerweise) gleichzeitig mit Vim das kleine Programm xxd installiert. Dieses sollte also auf jedem System zu finden sein, auf dem Vim installiert ist.

Wenn man Binärdateien öffnet, sollte man die Option -b von Vim nutzen, was den Binärmodus anschaltet:

vim -b datei.bin

xxd kann nun mittels eines Filters auf die geöffnete Datei angewendet werden:

:%!xxd

Damit wird aus dem folgenden Inhalt

Ein Test

die Hex-Repräsentation

00000000: 4569 6e20 5465 7374 0a                   Ein Test.

Die Zahl vor dem Doppelpunkt ist das Offset des ersten Zeichens in der Zeile (in hexadezimaler Schreibweise), also das wievielte Zeichen es ist. Danach folgt die hexadezimale Repräsentation der Zeile bestehend aus (bis zu) 16 Bytes. Danach sieht man die ASCII-Repräsentation der Zeile.
Nun kann man die hexadezimale Repräsentation beliebig ändern, wobei jedoch die ASCII-Repräsentation so bleibt, wie sie war. Sie wird nicht automatisch geändert.

Wenn man mit der Bearbeitung fertig ist, kann man xxd mit der Option -r aufrufen um wieder zur normalen Ansicht zurück zu kehren:

:%!xxd -r

Für die xxd Kommandos kann man sich nun Mappings erstellen. Dafür fügt man die beiden folgenden Zeilen in die ~/.vimrc ein:

map <leader>hex :%!xxd<CR>
map <leader>nhex :%!xxd -r<CR>

Nun kann man mittels \hex in den “Hexmodus” wechseln und mit \nhex wieder zurück. (Den Leader kann man z.B. mit der Zeile let mapleader="," auf , setzen, so dass man die Befehle mit ,hex und ,nhex aufrufen kann)

Das Plugin hexman
Das Bearbeiten von Dateien in der hexadezimalen Repräsentation wird durch das Plugin hexman erleichtert. Nachdem man die Datei hexman.vim ins Pluginverzeichnis (~/.vim/plugin) kopiert hat, kann man einfach folgende Befehle nutzen (Leader wird hier als \ angenommen):

  • \hm – wechselt zwischen Hexmodus und normalem Modus
  • TAB – bewegt den Cursor zum Anfang des nächsten ASCII Zeichens (da ein Zeichen ja aus 2 Hex-Ziffern besteht)
  • \hd – löscht das Zeichen unter dem Cursor
  • \hi – fügt ein ASCII-Zeichen vor dem Cursor ein
  • \hg – Springt zu einem Offset

In der Statuszeile wird jeweils das aktuelle Offset (des Cursors) in dezimaler und hexadezimaler Schreibweise angezeigt. In der ASCII-Repräsentation wird die Spalte hervorgehoben, in der sich der Cursor in der Hex-Repräsentation befindet. Wenn man die Befehle des Plugins zum Ändern von Werten benutzt, wird die ASCII-Repräsentation automatisch aktualisiert, so dass sie immer mit den Hexadezimalwerten überein stimmt.

Auch hier ist ein Mapping vorteilhaft, welches einem das Ändern eines Zeichens mittels \hc erlaubt:

map <leader>hc <leader>hd <leader>hi

NaturalDocs – Quelltexte natürlich dokumentieren

7. Juni 2009 von zimon
NaturalDocs Dokuementation des zBot

NaturalDocs Dokuementation des zBot

Da mir POD/PerlDoc nicht gefällt, habe ich mich vor einiger Zeit auf die Suche nach einer Alternative gemacht und bin auf NaturalDocs gestoßen. Mit diesem System können eine ganze Reihe von Programmiersprachen dokumentiert werden, wie z.B. perl, C#, c++, Makefiles, Ruby, Python, PHP, ActionScript, Java, JavaScript, Pascal, ADA, TCL, …

Sehr schön an NaturalDocs ist, dass die Dokumentation sehr nahe an natürlichsprachlichem Plaintext ist und sich die Beschreibungen von Klassen oder Methoden auch sehr gut aus den Quellen lesen lässt ohne dass man die Syntax von NaturalDocs kennen muss. Auch einfache Textdateien wie eine Readme oder ähnliches können damit erstellt werden. So kann man (zumindest bei kleineren Projekten) sogar sämtliche Dokumente wie Anforderungen, UML-Diagramme, … mit NaturalDocs erstellen, wodurch man alle Informationen an einem Ort gebündelt und in einem einheitlichen Format vorliegen hat.

Das Perl-Tool versteht auch JavaDoc, so dass eine Umstellung erleichtert wird.

Gestartet wird NaturalDocs mittels:
NaturalDocs -i [input (source) directory]
-o [output format] [output directory]
-p [project directory]
[options]

wobei ich mir ein kleines Script zum erstellen/aktualisieren der Dokumentation erstellt habe, welches ein Changelog beinhaltet, welches aus einem svn log automatisch generiert wird. Das Script habe ich unten angehängt.

Ein Beispiel in perl:

# SUB: multiplicate
# 
# multiplicates two numbers
# 
# PARAMETERS:
# $a - first parameter
# $b - second parameter
#
# RETURNS:
# the product of $a and $b
sub multiplicate {
    $a=shift;
    $b=shift;
    return $a*$b;
}

So sieht die Dokumentation einer einfachen Funktion aus. Bei Sprachen die full language support besitzen (bisher perl, ActionScript und C#) kann auch eine JavDoc-artige Dokumentation genutzt werden:

##
# multiplicates two numbers
# 
# PARAMETERS:
# $a - first parameter
# $b - second parameter
#
# RETURNS:
# the product of $a and $bsub multiplicate {
    $a=shift;
    $b=shift;
    return $a*$b;
}

Beide Beispiele haben das selbe Ergebnis:

NaturalDocs Beispiel

NaturalDocs Beispiel

Listen können erstellt werden, indem eine Zeile mit “-” angefangen wird. Definitionen haben ein “-” zwischen Bezeichner und Definition. Es können auch Grafiken, Beispielquelltexte und ASCII-Diagramme eingefügt werden.

Leider kann NaturalDocs von Haus aus nicht mit Listen in Listen umgehen, doch dafür gibt es einen Patch: Nested Bullets, womit man durch + oder * eine Liste in der Liste einleitet.
Installiert wird es, indem die Datei Native.pm.diff nach $NATURALDOCS_PATH/Modules/NaturalDocs/Parser Kopiert wird und dann der Befehl

patch Native.pm Native.pm.diff

aufgerufen wird.

Einen neuen Absatz erzwingt man durch eine Leerzeile. Eine Überschrift kann mittels # Überschrift: eingefügt werden, wobei die Zeile darüber leer sein muss.
Es kann auch auf Webseiten, Emailadressen und andere Stellen der Dokumentation verlinkt werden.
Natürlich kann auch unterstrichen und fett geschrieben werden. Die Zusammenfassung wird automatisch erstellt.

Cool ist auch die Möglichkeit der Abkürzung, womit man mehrere Defines, Funktionen oder Variablen zusammenfassend dokumentieren kann. So kann man statt dem folgenden Code

# VARIABLE: $configFile
# Filename of configuration file
$configFile = "config.txt";
 
# VARIABLE: $inputFile
# Filename of input file
$inputFile = "input.txt";
 
# VARIABLE: $outputFile
# Filename of output file
$outputFile = "out.txt";

die Variablen für die Dateinamen zusammen fassen:

# VARIABLES: Filenames
# $configFile - Filename of configuration file
# $inputFile - Filename of input file
# $outputFile - Filename of output file
$configFile = "config.txt";
$inputFile = "input.txt";
$outputFile = "out.txt";

Dabei können mehrere solcher Blöcke für verschiedene Belange angelegt werden (z.B. Dateinamen, Logindaten für Datenbank, …). Das Ergebnis sieht dann so aus:

NaturalDocs - Variablen zusammenfassend dokumentiert

NaturalDocs - Variablen zusammenfassend dokumentiert

Auch mein Jabber Bot zBot ist mit NaturalDocs dokumentiert. Als Beispiel kann man sich dessen Dokumentation ansehen.

Für Neulinge gibt es ein schönes Walktrough, wo die ersten Schritte mit NaturalDocs erklärt werden.

Hier noch das Script, welches eine von NaturalDocs lesbare Changelist im Ordner documents und dann die Dokumentation selbst erstellt:

#!/usr/bin/perl
 
# Script: makedocs.pl
#
# This script generates the documentation.
#
# Requirements:
#
# - NaturalDocs path must be in ENV variable $NATURALDOCS_PATH
# - Projectdirectory naturaldocs has to be in the same directory as this script
# - There must be a (empty) directory documentation in the same directory as this script
#
# Usage:
#
# Just start this script when something has changed or use the script <make.pl>
#
# > tools/makedocs.pl [OPTIONS]
#
# Options:
#
#  -o - start makedocs.pl in offline modus
#
# In offlinemode the changelog is not generated
#
#
# SVN:
#
# Commit only the textfiles of the projectdirectory (Not the directory "Data") from NaturalDocs.
#
# The documentation directory should be an empty dir in SVN.
#
# So everybody can create the documentation by himself just by executing this script.
 
use strict;
use warnings;
use vars qw (%ENV);
 
# Sub: generatechangelog
#
# Generates documents/changelog.txt from svn log -v
#
sub generatechangelog {
    print "Generating changelog...n";
    $ENV{LANG} = "C";
    my $log = `svn log -v`; 
 
    $log =~ s/(-){2,}//g;
    $log =~ s/(r[0-9]{1,4})/$1:nn$1/g;
    $log =~ s/n/nn/g;
    $log =~ s/Pfade:/Pfade/g;
    $log =~ s/paths:/paths/g;
    $log =~ s/([A-Z] /)/- $1/g;
 
    open(DATEI, ">documents/changelog.txt");
    print DATEI "Title: Changelognn$log";
    close DATEI;
    print "Done.n";
}
 
######### PROGRAM START ############
 
if (defined $ENV{NATURALDOCS_PATH} && $ENV{NATURALDOCS_PATH} ne "") {
    generatechangelog() if (not(defined @ARGV && $ARGV[0] eq "-o"));
# Generate documentation of current directory in HTML and save to directory documentation. Projectdirectory is naturaldocs.
# Ignore directory tests
    system
"$ENV{NATURALDOCS_PATH}/NaturalDocs -i . -o HTML ./documentation -p ./naturaldocs -xi ./tests";
} else {
    print "Environment variable $NATURALDOCS_PATH not defined!n";
}

Perl Einzeiler auf der Konsole

3. Juni 2009 von zimon

Ähnlich wie bei awk kann man perl das Programm auf der Konsole direkt übergeben. Dazu ruft man perl mit der Option -e auf. Das Programm muss dann in Hochkommata eingeschlossen werden.
Beispiel:

perl -e 'print "Hello World!\n"'

Um jede print-Anweisung mit einem “newline” abzuschließen, kann man zusätzlich die Option -l benutzen:

perl -l -e 'print "Hello World!"; print "Hello Ubuntuusers!"'

Um eine Datei Zeile für Zeile durchzugehen, gibt es die Option -n. Das Program beschreibt dann ähnlich wie bei awk was mit jeder Zeile geschehen soll:

perl -n -l -e 'print $_ if $_ =~ /foo/"' datei.txt

gibt alle Zeilen aus, die “foo” enthalten.
Die Option -n entspricht folgendem Code:

while(<>){
    # Der Code, der übergeben wird
}

Die Option -a bringt perl noch einen Schritt näher zu awk. Damit werden die Wörter einer Zeile (die durch Leerzeichen getrennt sind) in das Array @F geladen. Den Worttrenner kann man mit der Option -F setzen:

perl -n -a -F; -e 'print $F[$#F]' datei.csv

gibt von jeder Zeile das letzte Element einer csv (Comma Separated Value) Datei aus.
Dies entspricht folgendem Code:

while(<>){
    @F = split($pattern);
    # Der übergebene Code
}

wobei $pattern das mit -F übergebene Pattern (im obigen Beispiel ";") ist. Dadurch sind auch reguläre Ausdrücke wie -F/[0-9]+/ möglich.

Es können auch die Schlüsselwörter BEGIN und END gesetzt werden um einen Block vor oder nach der Hauptschleife auszuführen:

perl -n -l -a -e 'BEGIN{$x=0} {$x+=$F[$#F]} END{print $x}' preisliste.txt

errechnet den Gesammtpreis einer Preisliste, in der am Ende jeder Zeile der Preis steht. Es wird also von jeder Zeile das letzte Wort addiert. Man könnte das Programm jetzt auch noch etwas kürzer schreiben:

perl -nlae '$x+=$F[$#F]; END{print $x}' preisliste.txt

Dies entspricht dem awk-Programm:

awk '{x+=$NF} END{print x}' preisliste.txt

Für das Suchen und Ersetzen mit Regulären Ausdrücken eignet sich die Option -p. Diese Funktioniert genau wie -n mit dem Unterschied, dass jede Zeile automatisch ausgegeben wird. So kann man wie mit sed Dateien ändern:

perl -pe 's/foo/bar/g' datei.txt > datei_new.txt

ersetzt jedes Vorkommen von “foo” durch “bar” und schreibt das Ergebnis in die Datei “datei_new.txt”.

Um die Datei direkt zu ändern, kann man die Option -i verwenden. Dieser kann optional ein String mitgegeben, der an den verwendeten Dateinamen angehängt den Dateinamen einer anzulegenden Sicherheitskopie ergibt:

perl -pi -e 's/foo/bar/g' *.txt
perl -pi.orig -e 's/foo/bar/g' datei.txt

Beim ersten Befehl jede Text-Datei im aktuellen Verzeichnis direkt geändert. Beim zweiten wird die “datei.txt” nach “datei.txt.orig” kopiert bevor jedes Vorkommen von “foo” durch “bar” ersetzt wird. (Man kann natürlich auch mit dem 2. Befehl beliebig viele Dateien bearbeiten, wenn man * benutzt.)

Module
Die Option -M erlaubt es einem beliebige Module einzubinden, die dann im Programm benutzt werden können. So kann man z.B. mit dem folgenden Befehl mit dem Modul LWP::Simple eine Webite laden und den HTML-Code ausgeben:

ls | perl -MLWP::Simple -e 'getprint("http://zinformatik.de")'

Mit dem folgenden Befehl werden von allen iso Dateien im Verzeichnis MD5-Summen erstellt:

ls *.iso | perl -MDigest::MD5 -nle 'open(FILE,$_); $d=Digest::MD5->new; $d->addfile(FILE); print $d->hexdigest'

Fazit
Für kleinere kosmetische Änderungen eines Textes oder einer Ausgabe sowie zum extrahieren von Informationen daraus ist awk meist besser geeignet. Bei komplexeren Aufgabenstellungen ist die Mächtigkeit von perl jedoch vorteilhafter.
Vor allem durch die Möglichkeit der Dateioperationen sollen manche Aktionen beschleunigt werden können:
Statt des Aufrufs:

find -name "*.bak" -exec rm "{}" \;

der für jede gefundene Datei einen neuen Prozess startet um sie zu löschen kann man folgenden Befehl nutzen:

find -name "*.bak" -print | perl -nle 'unlink'

Es ist jedenfalls nicht verkehrt beides zu kennen, ganz nach dem Motto: Für jeden Zweck die richtige Programmiersprache.

[UPDATE]Mehr informationen liefert der Befehl perldoc perlrun (perldoc muss installiert sein) oder die Seite http://p3rl.org/perlrun[/UPDATE]

Verschiedene Undo- und Redo-Möglichkeiten für Vim

31. Mai 2009 von zimon

Neben den Standardvarianten, die jeder Editor beherrscht bietet vim noch mehr Kommandos für Undo und Redo. Die beiden geläufigsten Kommandos sind wohl u für Undo und Strg+r für Redo, die beide mit Quantifizierern aufgerufen können (z.B. 3u nimmt 3 Änderungen zurück). Mit U nimmt man alle letzten Änderungen der aktuellen Zeile zurück.

Einige kennen vielleicht das Problem, wenn man etwas mit Undo Rückgängig macht und dafür etwas anderes hinschreibt und irgendwann möchte man in den Zustand vor dem Undo zurück. Doch das ist mit den beiden “Standardkommandos” nicht möglich. Daher gibt es bei Vim die Befehle g- und g+, sie gehen zeitlich gesehen je einen Zustand zurück oder vor und können ebenfalls mit Quantifizierern verwendet werden.

Ein Beispiel:
Man schreibt folgenden Satz wobei man nach jedem Wort ESC drückt, damit jedes Wort per Undo zurückgenommen werden kann:

Dies ist ein Beispiel

Nun nimmt man mit u das letzte Wort zurück und ersetzt es mit dem Wort “Test”.

Dies ist ein Test

Jetzt kann man mit u und Strg+r zwar jedes Wort zurück nehmen und wieder setzen, aber man kommt nicht zum ersten Satz mit “Beispiel” zurück. Drückt man statt dessen g-, wird zum ersten Satz mit “Beispiel wieder hergestellt (solange vorher nicht u gedrückt wurde, sonst muss man mit g+ arbeiten).

Vim speichert die Undo und Redo Schritte in einer Baumstruktur, wobei Undo nur eine Stufe höher geht und Redo in den jeweils neuesten Zweig. Dadurch kommt man im obigen Beispiel mit diesen Kommandos nicht mehr in den Zweig, wo der Text das Wort “Beispiel” enthielt. g+ und g- hingegen traversieren den gesamten Baum, wodurch jeder Zustand, der einmal existierte hat wieder hergestellt werden kann.

Ähnlich funktionieren die Kommandos :earlier und :later. Sie haben ohne Argument (oder nur mit Quantifizierer wie z.B. :earlier 3) die gleiche Funktionen wie g+ und g-. Man kann ihnen aber auch Zeitangaben in Sekunden, Minuten und Stunden mitgeben, zu denen gesprungen werden kann:

  • :earlier 30s – springt zum Zustand,der vor 30 Sekunden herrschte.
  • :earlier 5m – stellt den Zustand von vor 5 Minuten wieder her.
  • :earlier 2h – läd den Zustand von vor 2 Stunden.
  • :later 20m – Zeigt den Text, wie er 20 Minuten später aussah.

Das Kommando later kennt natürlich auch die Sekunden- und Stundenangaben.

Mit dem Befehl :undol bzw. :undolist kann man sich die Liste aller Änderungen anzeigen lassen. Dabei werden einem alle Zweige des Baumes aufgelistet und angegeben wieviele Änderungen es in dem Zweig gab sowie der Zeitpunkt, an dem die Änderung gemacht wurde.

zInformatik ist jetzt auch bei Twitter

24. Mai 2009 von zimon

Ich glaub es selbst kaum, aber ich bn jetzt bei Twitter. Vor einigen Wochen noch habe ich mir noch gesagt, dass ich sowas wohl nie machen werde und die Leute nicht verstehe, die da öffentlich ihr Leben ausbreiten (das ist auch der Grund warum ich sonst in keinem sozialen Netzwerk Mitglied bin).
Vor einem knappen Jahr hatte ich mir Twitter mal angesehen, ein paar sinnlose Dinge reingeschrieben und es dann gelassen.
Dann vor einigen Monaten las ich darüber, dass man Twitter auch dazu nutzen könnte, sich über interessante Neuigkeiten und ähnliches zu informieren. Mein Problem dabei war jedoch, dass ich nur Twitterer/Tweeter/Tweets (oder wie die Leute auch immer heißen, die twittern bzw. deren Mikroblogs, ich nenn sie jetzt mal Tweeter, da ein Tweet afaik ein einzelner Twitter-Eintrag ist) gefunden habe, die auf Twitter ihr Leben ausbreiten oder mit anderen Leuten am Chatten sind. Somit habe ich dann endgültig für mich beschlossen, das Twitter nichts für mich ist – dachte ich.

Gestern Abend fragte meine Freundin, ob ich ihr nicht Twitter einrichten könne, da sie gehört hat, dass dies mehr Besucher auf ihrem Blog bringen soll. Man kann nämlich mit dem Plugin Twitter Tools automatisch die Überschriften seiner Blogbeiträge twittern.
Das habe ich ihr natürlich gleich eingerichtet und dabei ist mir die Idee gekommen, wofür ich twitter sinnvoll nutzen könnte.
Einmal natürlich als RSS-Ersatz, für Leute, die lieber über Twitter informiert werden statt RSS.
Zum anderen kann ich dort interessante Webseiten und kleine Tipps Posten, die für einen Blogeintrag nicht reichen.

Und genau dies habe ich nun angefangen. Ich nahm meinen alten Twitter-Account und habe mir auch das Twitter Tools Plugin installiert. Nun schreibe ich alle möglichen Tipps und Tricks, die mir so unterkommen sowie Webseiten und interessante Blogposts auf Twitter. Diese werden auch auf dem Blog in der Sidebar angezeigt (dies wird auch von Twitter Tools unterstützt). Wie lange und wie regelmäßig ich so twittern werde kann ich noch nicht sagen, ich probiere es erstmal aus.

Allerdings habe ich immer noch das Problem, Tweeter zu finden, die überwiegend interessante Dinge posten und weniger darüber erzählen, was sie gerade so tun (Kaffee holen, Programmieren, …). Wenn jedoch nur Blogeinträge getwittert werden, so abonniere ich mir lieber den RSS-Feed des Blogs. Einige habe ich schon gefunden. Wenn jemand noch mehr kennt, würde ich mich über einen Kommentar darüber freuen.
Bisher finde ich folgende Tweeter recht interessant:

  • http://twitter.com/ChrisZwitschert – schreibt viel über News rund um die IT-Welt sowie Tipps. Schwerpunkt auf Ubuntu/Linux
  • http://twitter.com/peddy76 – hat zwei Mal meinen Blog verlinkt :-) und schreibt meist über Vim. Twittert aber nur, wenn es wirklich was zu sagen gibt.
  • http://twitter.com/aptgetupdate – Twittert auch viele IT-News
  • zInformatik ist nun bei Twitter unter http://twitter.com/zInformatik erreichbar

    [UPDATE]Ist manchmal garnicht so leicht etwas in 140 Zeichen auszudrücken.
    Ich werde wahrscheinlich – wie schon in den Kommentaren erwähnt – die Twitterbeiträge Teilweise in Blogbeiträgen zusammen fassen (z.B. zu einem 2. Teil der Vim Tipps) oder etwas genauer auf einige Dinge eingehen.
    Wer sich nicht bei Twitter anmelden möchte um mir zu folgen, kann dort auch den RSS-Feed Abonnieren (in der Seitenleiste).[/UPDATE]

Less is more (than more) – weniger ist manchmal mehr

23. Mai 2009 von zimon

Viele kennen less, das Programm zum Anzeigen von Textdateien. Ich habe es mir nun einmal etwas genauer angesehen.
Mit less lassen sich auch große Textdateien sehr schnell anzeigen, da es schon mit der Darstellung des Textes beginnt, wenn die Datei noch nicht vollständig geladen ist.
Auch zum Anzeigen von Kommandozeilenausgaben ist less sehr nützlich. Dafür braucht man die Ausgabe nur in less zu pipen, z.B. so:

ls -lh | less

Die vim-User wird es freuen, dass viele Kommandos die gleichen wie bei vim sind oder ihnen zumindest ähneln.

Navigation
Navigieren kann man in less neben den Pfeiltasten wie in vim mit h,j,k und l. (Strg+)u und (Strg+)d sowie (Strg+)f und (Strg+)b haben die Funktion, halbe bzw. ganze Bildschirmseiten herunter und hoch zu springen. Die Strg-Taste ist dabei optional. Auch mit Space kann man einen Bildschirm herunter scrollen.
g springt zum Anfang und G zum Ende des Dokuments.

Man kann sich auch anzeigen lassen, welche Zeile die erste ungelesene im Text ist, wenn man mehr als eine Zeile hinunter scrollt. Diese wird dann markiert. So findet man schnell die Stelle wieder, an der man aufgehört hat zu lesen. Dazu startet man less mit der Option -W.

Less kennt auch Markierungen wie vim. Allerdings sind diese immer Dateiübergreifend und es können nur Kleinbuchstaben genutzt werden. Mit m{Marke} (wobei {Marke} ein Kleinbuchstabe ist) kann eine Zeile Markiert werden und mit {Marke} zu ihr hingesprungen werden ( ist das Hochkomma mit Shift+#). Mit (zwei Hochkommata)kann man zwischen zwei Markierungen hin- und her springen.

Anzeigen von mehreren Dateien
Indem man less mehrere Dateinamen als Argumente übergibt, kann man sich auch viele Dateien anzeigen lassen. Zwischen den Dateien springt man mit :n (zur nächsten) und :p (zur vorherigen). Natürlich kann man auch die Markierungen nutzen um zwischen den Dateien zu springen. Um aus less heraus eine neue Datei zu öffnen, kann man :e <Dateiname> eingeben. Mit :x gelangt man zur ersten Datei, während man mit :d die aktuelle Datei schließt.

Suchen im Dokument
Die Suche bei less funktioniert wie bei vim mit /<Suchpattern>. Mit n und N kann man zum nächsten bzw. vorherigen Treffer springen. Um die bei der Suche Groß- und Kleinschreibung zu ignorieren startet man less mit der Option -i. Dies entspricht der intelligenten Suche, die Groß- Kleinschreibung nur dann beachtet, wenn im Suchbegriff auch Großbuchstaben vorkommen. -I entspricht dann einem wirklichen ignore-case.
Wie in vim wird mit ? in die entgegengesetzte Richtung gesucht.

Coole Funktionen
Less wäre nicht more wenn es nicht mehr gäbe.
Alle Aufrufoptionen (die, die mit - anfangen) lassen sich auch einfach bei laufendem Programm eingeben (einfach eintippen), während Kommandos beim Aufruf durch ein vorangestelltes + mitgegeben werden können (z.B. öffnet less +G <Dateiname> eine Datei und springt sofort ans Ende).

  • Mit v öffnet man vim mit der aktuellen Datei. (Bzw. den in der Umgebungsvariablen EDITOR angegebenen Editor)
  • Mit F wird ans Ende der Datei gesprungen und diese bei jeder Änderung aktualisiert. Damit kann man sehen, wenn etwas z.B. in Logdateien hinzukommt. Dies entspricht einem tail -f. Zurück zm normalen Modus kommt man mittles Strg+c
  • Mit der Option -M gibt less mehr Informationen (Zeilennummer und Länge sowie relative Position im Dokument) aus.
  • Die Funktion = gibt noch mehr Informationen aus.
  • Die Option -e veranlasst less dazu sich zu beenden, sobald das Dateiende zwei mal erreicht wurde. Mit -E wird less schon beim ersten Erreichen des Dateiendes geschlossen.
  • Sehr praktisch finde ich auch die Option -F, bei der sich less automatisch schließt, wenn der Text auf eine Bildschrimseite passt. So wird der Text ausgegeben und less dann beendet.
  • Durch !<Kommando> kann man ein Shell-Kommando ausführen, wobei man die Variable % für den aktuellen Dateinamen nutzen kann.
  • Mit s <Dateiname> wird (wenn man sich die Ausgabe eines Programms anzeigen lässt) die Ausgabe in der angegebenen Datei gespeichert.
  • Durch die Option -R zeigt less auch die Farben an, wenn man ein grep oder ls mit der option –colors=always hinein piped.

Eigene Tastenkombinationen definieren
Less hat auch eine eigene Konfigurationsdatei: ~/.less mit der man eigene Keybindings definieren kann.
Diese wird im Format Keybinding Action angegeben, wobei jede Zeile nur ein Keybinding besitzen darf.
Beispiele und mögliche Keys und Aktionen findet man in der manpage zu lesskey.

Eigenen Prompt definieren
Statt der Option -M kann man sich auch einen eigenen Prompt mit der Option -P definieren. Dafür gibt es jede Menge Variablen und Abfragen, dass man z.B. nur dann den Dateinamen ausgibt, wenn auch eine Datei gelesen wird und nicht von STDIN. Hier ein Beispiel:

?f%f:Standard input

gibt den Dateinamen aus oder “Standard input” wenn ein Kommando in less gepiped wurde.
Die ganzen Variablen und Abfragen sind in der manpage dokumentiert.

Preprozessor-Funktionen
Ich möchte noch kurz erwähnen, dass man für less Funktionen definieren kann, die vor dem Öffnen eines bestimmten Dateityps ausgeführt werden. So kann man z.B. eine Datei zuerst entschlüsseln oder dekomprimieren, bevor man sie anzeigen lässt. Eine entsprechende Funktion, der vor dem Schließenausgeführt wird um z.B. temporäre Dateien zu löschen kann ebenfalls definiert werden.
Weitere Infos dazu gibt es in der manpage.



Weitere Funktionen und Informationen bekommt zu less man wie immer in der manpage.


Bloggeramt.de frisch gebloggt Blogverzeichnis - Blog Verzeichnis bloggerei.de