www.thomas-guettler.de / Vorträge
niemand.leermann@thomas-guettler.de
Güttli's Tipps und Tricks der EDV

Ich habe etwa im Jahr 2000 mit einer Text-Datei namens readme.guettli angefangen. Dort wurden kleine Shell-Scripte und Argumente für Befehle aufgeschrieben, die man im Beruf oder in der Freizeit immer wieder benötigt. Im Laufe der Zeit wurde die Datei überarbeitet und steht hier nun schon mehrere Jahre für andere zur Verfügung.

Während eine sachliche Beschreibung von Software meistens vorhanden ist, fehlt oft eine subjektive Wertung. Darum stelle ich außerdem meine Sichtweise vor. Da für jedes Problem mehrere Lösungsmöglichkeiten existieren, hoffe ich mit Hinweisen wie "ich finde aufgrund XYZ Programm A besser als Programm B" Einsteigern zu helfen.

Inhaltsangabe
Linux vs. Windows
Linux Hardware
Interaktive Programme
Shell
Sonstiges
Programmiersprachen
Web-Design und Web-Entwicklung
X-Windows
Cygwin
10  XML
11  Persönliche Meinung
12  Leseempfehlungen
13  About

1 Linux vs. Windows [toc]

Die Diskussion ob Linux besser ist als Windows ist immer wieder interessant. Da es die meisten Unix-Programme für Windows gibt, jedoch die wenigsten Windows-Programme für Linux, verstehe ich jeden Anwender der nicht zu Linux wechseln will. Siehe auch: oss4win: Open Source Software für Windows.

Als Betriebssystem für Server und als Plattform für Softwareentwicklung, verwende ich auf jeden Fall ein freies Unix.
Aufgabe Windows Linux
Zeichenkodierung von Dateien/Verzeichnissen Unter Windows hat man weniger Probleme, da immer mit Unicode gearbeitet wird. Die Kodierung kann beim Mounten (Einbinden) angegeben werden. Durch die Vielzahl der Kodierungsmöglichkeiten, gibt es öfters Probleme bei Umlauten in Dateinamen.
Serverprozesse Windows unterstützt folgende Funktionen nicht:
  • select() auf Pipes
  • fork()
  • pass_fd: Offene Filedescriptoren zwischen Prozessen austauschen
Linux ist wie die meisten Unix-Systeme gut geeignet für Serveranwendungen. In einer kleinen Sache ist jedoch Windows besser: Die IO-Last eines Prozesses kann untersucht werden. Unter Linux ist das nicht möglich.
Anwendungen Unter Windows gibt es viele GUI-Anwendungen. Alles schön bunt. Viel Spaß beim Klicken. Unter Linux gibt es viele Serveranwendungen. Mail-, DNS-, Web-, Zeitserver .... Alles schön stabil. Viel Spaß beim Netzwerkeln. Eine Alternative zum Zeichenprogramm MS-Viso gibt es aber derzeit für Linux nicht (Dia, Inkscape, OpenOffice Draw sind noch nicht so gut).


Mein Tipp: Nimm was dir gefällt. Probiere beides aus.

2 Linux Hardware [toc]

Generell: Augen auf beim Hardware kauf. Lieber vorher im Web suchen ob die Hardware von Linux unterstützt wird. Wer sich mit Linux beschäftigt, sollte wissen, dass es sich dabei um ein Betriebssystem handelt, das besonders für Server gut geeignet ist. Linux ist kein Multimediaspielzeug. Mit modernen Multicore Prozessoren ist ein Software-RAID meist schneller, preisgünstiger und flexibler zu konfigurieren als ein Hardware-RAID. Die zusätzliche CPU Belastung spielt kaum eine Rolle. IDE-Festplatten Konfigurieren.
    32-Bit Zugriff und DMA aktivieren:
    
    root> hdparm -m16 -d1 -c3 -X69 /dev/hd?
    
     -m   Übertragen mehrerer Sektoren pro Interrupt
     -d   DMA
     -c   32 Bit I/O
     -X69 UltraDMA mode5
     -u1  Unmaks Interrupts: Andere Interrupts kurzzeitig ignorieren

    Falls diese Einstellungen funktionieren -k1 hinzufügen (keep-settings) 

    Performance der Festplatte testen:
    root> hdparm -tT /dev/hd?
Grub ist ein leistungsfähiger Bootloader und eine bessere Alternative zu Lilo (Linux Loader). Der Bootloader wird nach dem Starten des Rechners ausgeführt um dann das Betriebsystem zu starten. Grub bietet dem versierten Benutzer eine kleine Shell. Problemstellung: Auf der Festplatte befinden sich mehrere Unix-Betriebssysteme. Doch wie kann man das System booten, dass einen bestimmten Hostnamen hat?
# Ggf. mit ESC und anschließend "c" aus dem grafischen Modus in den 
# interaktiven Modus wechseln

find /etc/fstab
 --> Es werden alle verfügbaren Dateisysteme nach der angegebenen Datei
     durchsucht. Der Dateinamen muss ein absoluter Pfad sein. Im Gegensatz
     zu dem Befehl "find" der Shell, wird nur überprüft ob diese Datei
     auf einer Partition vorhanden ist.

 Typisches Ergebnis:
 (hd0,5)   == /dev/hda6
 (hd0,7)   == /dev/hda8
 (hd0,8,a) == BSD Slice
 (hd1,1)   == /dev/hdb2

# Dateien anzeigen
cat (hd0,5)/etc/hostname  (SuSE /etc/HOSTNAME)
  --> Anzeigen der Datei

# System Starten
root (hd0,5)
kernel /vmlinuz  root=/dev/hda6 (SuSE /boot/vmlinuz)
initrd /initrd.img (SuSE /boot/initrd)
boot
Die Konfiguration findet man in "/boot/grub/menu.lst". Falls sich Grub mit obiger Fehlermeldung beim Booten beendet, kann er nicht auf die nötigen Dateien (z.B. (hd0,5)/boot/grub/...) zugreifen. Das kann passieren, wenn z.B. Partitionen gelöscht wurden, so dass aus (hd0,5 (/dev/hda6)) (hd0,4 (/dev/hda5)) wird. Wie kann man dann sein System retten?
  1. Eine Installations-CD einlegen, die Grub verwendet (z.B. Ubuntu-Live-CD). Den grafischen Modus von Grub mit ESC verlassen, und mit "c" in den Kommandomodus wechseln. Dann wie oben beschrieben booten.
  2. Das alte System sollte wie gewohnt starten. Falls dass nicht funktioniert, kann man auch ein Livesystem (Knoppix, Ubuntu Installations-CD) starten und anschließend das Rootsystem unter /mnt mounten und dann mit chroot dort hineinwechseln.
  3. Die Datei "/etc/fstab" anpassen.
  4. Anschließend "/boot/grub/menu.lst" anpassen.

    Bei Debian/Ubuntu, folgende Zeilen verändern:
    # kopt=root=/dev/hda7 ro
    ...
    # groot=(hd0,6)
    Anschließend /sbin/update-grub aufrufen.
  5. Live-CD entfernen, Neustarten und hoffen, dass das System wieder startet.

3 Interaktive Programme [toc]

Die Readline Bibliothek wird von vielen Programmen verwendet. Allen voran der Shell "Bash". Die Readline Bibliothek wird auch in vielen anderen Programmen eingesetzt: Python im interaktiven Modus, MySQL Befehlszeile ...
   > set -o emacs
   --> Falls der vi Mode eingestellt ist kann man so zum emacs Mode
    wechseln. (Emacs ist der Default-Wert)

   Pfeil-hoch/runter: Blättern in der History
   ctrl-a: Anfang der Zeile
   ctrl-e: Ende der Zeile
   ctrl-r: Rückwärts in der History (letzte Eingaben) suchen
   ctrl-k: Bis Ende der Zeile löschen
   ctrl-y: Einfügen von gelöschten Bereichen
   ctrl-d: Aktuelles Zeichen löschen
Tricks der Bash:
   $_: letzte Argument des letzten Befehls (Bsp: mkdir beispiel; cd $_)

   ESC .: letzte Argument des Befehls an Cursor Position einfügen.
          Oder "ESC 1 ESC .": Erstes Argument des letzten Befehls einfügen

   Anstatt ESC und anschließend "." drücken, kann man auch die
   Alt-Taste halten und gleichzeitig "." drücken. Mit ALT-1 ALT-. kann
   man zum Beispiel in der Liste der letzten Argumente blättern.
Ich bevorzuge XEmacs, man sollte jedoch die wichtigsten Grundlagen des "vi" ebenfalls können. Darum habe ich auf folgender Seite eine Tabelle erstellt, die beide Editoren beschreibt:

Emacs Einführung Um zwei Dateien Zeile für Zeile zu vergleichen, kann man Folgendes verwenden:
diff -w -y -W 200 -t old.txt new.txt | less

 -w:     Ignoriere Änderungen die nur aus Leerzeichen bestehen
 -y:     Zeige die Dateien nebeneinander an
 -W 200: Verwende insgesamt 200 Zeichen in der Breite (Etwa 100 für old.txt, und 100 für new.txt)
 -t:     Geben keine Tabs, sondern Leerzeichen aus (Nötig, wenn less mit der Option -x4 (Ein Tab entspricht vier Leerzeichen) gestartet wird)
Schöne bunte Diffs kann man mit vimdiff oder ediff (Emacs) produzieren. Um Veränderungen an einer Datei zusammenzuführen benutze ich kdiff3. Es ist besonders gut geeignet um zwei unabhängig veränderte Versionen einer Datei zusammenzuführen:
    kdiff3 beispiel_base.c beispiel_aenderung1.c beispiel_aenderung2.c -m
Als Email-Programm verwende ich Mutt. Es ist ein textbasiertes Email-Programm. Diskussionen in Mailinglisten werden als sog. "Threads" dargestellt und Email lassen sich anhand regulärer Ausdrücke löschen/verschieben/kopieren.
    T tag messages according to regular-expression
    ; prefix, use command on tagged messages
    ~m [MIN]-[MAX]  message in the range MIN to MAX
    F Flag message (color)
   Beispiel: 
   Doppelte E-Mails mit Mutt löschen:
     1. T   --> Markieren nach Muster
     2. ~=  --> Markiere doppelte E-Mails (Anhand Message-ID)
     3. ;d  --> Lösche markierte E-Mails
     4. $   --> Speichern der Änderungen
Der Email Client Thunderbird läuft unter Windows, Linux und vielen anderen Betriebssystemen. Folgende Plugins verwende ich: Ein großer Nachteil: Thunderbird unterstützt bis jetzt nicht das Maildir Format. Die Emails speichere ich im maildir Format. Jede Email wird in einer Datei gespeichert. Locking-Probleme wie beim MBox Format gibt es nicht. Außerdem kann man bequem Mails löschen, die älter als N Tage sind:
   cd Maildir/foo-mailinglist/; find -type f -mtime +N | xargs rm
Nachdem ich lange mit der Syntax von Fetchmail und Procmail gekämpft habe, bin ich zu getmail gewechselt und damit sehr zufrieden. Mit getmail kann man Emails von einem POP3 oder IMAP Server herunterladen und in lokale Postfächer einsortieren. Aus meiner Sicht hat getmail folgende Vorteile:

3.6 Pager [toc]

Der Pager less ist eines der wichtigsten Werkzeuge auf der Kommandozeile. Er zeigt Ausgaben von Programmen oder ASCII-Dateien seitenweise an:

    > beispiel_command | less

    oder

    > less .bashrc

    Die wichtigsten Befehle:

     /     --> Suchen (n: Nächster Treffer; N: vorhergehender Treffer)

     F     --> wie "tail -f": Die Anzeige wird aktualisiert,
           falls neue Daten da sind. 
           Wieder zurück in den Pager-Modus mit ctrl-c.
           Kann auch beim Aufruf angegeben werden: "less +F datei.log"

     -S    --> Zu lange Zeilen werden nicht umgebrochen

     -jN   --> Bei einer Suche die passende Zeile N Zeilen unter dem oberen
             Ende des Terminals anzeigen. Hilfreich, wenn man an der Zeile
             interessiert ist, die über dem Suchbegriff steht.

     -U    --> Underline Special Characters (Carriage Return (^M) und Backspace (^I) werden hervorgehoben)
     
     :f    --> Informationen: Anzahl Zeilen, aktuelle Zeile, Prozent, ...

     g/G   --> Gehe zum Anfang/Ende der Datei

     20G   --> Gehe zur Zeile Nummer 20

     |<m>  cat > outfile
           --> Bereich zwischen Markierung <m> und aktueller Zeile in die
           Datei "outfile" umleiten. Bei großen Dateien werden die Editoren
           vim und Emacs sehr langsam.
Folgende Umgebungsvariable setze ich in .bashrc
    #less pager
    #q:  silent
    #Q:  allways quiet (Switching from "F" back)
    #i:  case insensitiv search
    #x4: Tab is four spaces (not eight)
    export LESS=-qQix4
Mit "+" lassen sich beim Aufruf Befehle angeben, die gleich ausgeführt werden:
  less +/path .bashrc        # Öffne .bashrc und suche nach "path"
  less +F /var/log/auth.log  # Öffne das Log-File und aktualisiere das Ende fortlaufend
Gimp ist ein Bildbearbeitungsprogramm (eine Alternative zu Photoshop). Es ist auch für Windows verfügbar. Bilder lassen sich mit Mirage sehr einfach sortieren. Mittels "Custom Action" kann man eigene Befehle mit der aktuellen Datei ausführen.
Beispiel:
Custom Action g: mv %F ~/images/gut/; [NEXT]
Custom Action n: mv %F ~/images/normal/; [NEXT]
Custom Action s: mv %F ~/images/schlecht/; [NEXT]
ImageMagick ist nicht wie Gimp ein interaktives Programm. Es ist eine Sammlung von Befehlen, um Bilder auf der Kommandozeile zu bearbeiten.

NetPBM ist eine Sammlung von kleinen Programmen die Bilder in dem einfachem PBM Format verarbeiten.

ImageMagick:

NetPBM:
  1. Bilder von dern Kamera holfen
    gphoto2 --get-all-files
    
  2. Bilder anhand der Exif-Orientierung drehen
    find -iname '*.jpg'| xargs exiftran -aip
    
  3. Bilder anhand des Erstellungsdatum umbenennen
    Das Programm exiftool kann mehr als der Name vermuten lässt. Es liest die Metainformationen nicht nur von Jpeg, sondern auch von AVI und RAW-Dateien.
    exiftool '-FileName<DateTimeOriginal' -d  "%Y/%m/%d/%Y%m%d_%H%M%S-%%.c.%%e"  directory
    
    Die Bilder werden umbenannt und tagesweise in Unterverzeichnisse gespeichert.
Ich bin ncftp sehr zufrieden. Er kann auch nicht interaktiv (in Shell-Scripten) verwendet werden: ncftpput, ncftpget. Das Programm Screen ist ein Terminal Multiplexer. Es ermöglicht in einem Terminal mehrere Terminals zu starten. Besonders praktisch ist, dass man sich von den Sitzungen ab- und wieder anmelden kann. Beispiel: Man möchte auf einem entfernten Server einen lang dauernden Prozess ausführen. Starten man den Prozess innerhalb von Screen, kann man sich von dem Terminal trennen, ohne den Prozess zu beenden. Anders, als bei dem Befehl "nohup", kann man sich mit dem Prozess auch wieder verbinden ("screen -r").

Falls man einen Prozess ohne screen gestartet hat, und sich gerne abmelden möchte, kann man wie folgt vorgehen: Leider ist Zip sehr verbreitet. Es komprimiert schlechter als gzip und bzip2.
    # Erstellen einer Zip-Datei:
    zip -r selfhtml /usr/share/doc/selfhtml
    --> selfhtml.zip

    # Inhaltsverzeichnis anzeigen:
    unzip -l selfhtml.zip
   
Eine tgz-Datei wird normalerweise mit zwei Befehlen erstellt, bzw dekomprimiert. Tar fasst ein Verzeichnis zu einer Datei zusammen. Die Datei ist nicht komprimiert. Diese Datei wird anschließend mit gzip komprimiert. Beide Schritte lassen sich mit einem Befehl erledigen:
    # Einpacken:
    tar -czf beispiel.tgz beispiel/

    # Inhaltsverzeichnis anzeigen:
    tar -tzf beispiel.tgz

    # Auspacken:
    tar -xzf beispiel.tgz
    
BZip2 komprimiert besser als gzip, ist aber nicht so verbreitet.
    > bunzip2 beispiel.bz2
	 
    oder anstatt "z" "j" für tar verwenden:

    > tar -xjf beispiel.tar.bz2
    
Mir ist es schon passiert, dass Daten, die als tgz 2.5 MByte Platz benötigen als tar.bz2 600 kByte groß waren. Das Programm Openoffice.org (OOo) ist ein alternative zu MS-Word, MS-Excel und MS-Powerpoint. Außerdem läuft es auch unter Linux. Das schönste ist jedoch das offene Dateiformat: Openoffice Dateien sind mit zip gepackte XML-Dateien. Um z.B. ein Bild zu extrahieren kann man mit "unzip" die Datei auspacken und dann sich die entsprechende Bild-Datei herauskopieren.

Oder man kann mit seiner Lieblingsscriptsprache Openoffice-Dateien erstellen.

Mit pyUNO kann man Openoffice mittels Scripten automatisieren. Beispiel: ooo2any.py.

4 Shell [toc]

Den Begriff "Shell" könnte man mit "Kommandozeile" übersetzten. Die Shell unter Unix ist einiges leistungsfähiger als die DOS-Eingabeaufforderung der Microsoft Betriebssysteme. Im Folgenden werden die Shell Bash und die üblichen Unix-Tools (GNU-Version) beschrieben. Die meisten Programme sind mittels cygwin auch für Windows-Betriebssysteme verfügbar. Bei den folgenden Startdateien sollte man darauf achten, dass alle Ausgaben nach stderr geschrieben werden (Siehe SSH), da sonst Programme wie "scp" annehmen, dass diese Ausgaben Teil der zu übertragenden Daten sind. Grep verwendet Reguläre Ausdrücke um Zeilen in der Textdatei zu finden. Wenn Dateien Leer- oder Sonderzeichen enthalten wird das Arbeiten mit Shell-Scripten unschön. Es ist aber nicht unmöglich:
   for file in `find .`; do ... geht leider nicht!
  
   find . | while read file
   do 
    bsp_command "$file"
   done
  
Bei obigen Beispiel muss man jedoch beachten, dass die Bash für die Zeilen der While-Schleife eine neue Subshell erstellt. Umgebungsvariablen, die man in setzt sind nach dem "done" nicht zu sehen, da sie nicht an die Eltern-Shell zurückgegeben werden. Obiges Beispiel ist aber nicht 100% sicher. Das Newlinezeichen ist in Dateinamen unter Unix zulässig. Das Lesen von Stdin würde jedoch darüber 'stolpern'. Mein Tipp: Die Shell vorwiegend nur interaktiv nutzen. Für Programme, die öfters benutzt werden: Python.
for file in `ls *.TTF`; do mv $file ${file%.TTF}.ttf; done
Näheres zu ${file%.TTF} finden man unter "Parameter Expansion" in "man bash". Nur eine Auswahl an Dateien in ein Zielverzeichnis verschieben:
find ... -print0 -name '*.png' |  xargs -0 mv --target-directory mydir
In Python haben Zeichenketten die praktische Funktion "endswith()". In der Bash ist das etwas komplizierter:
   if [ "${myvar: -3:3}" = "foo"]; then
     ....
   fi
Das Leerzeichen vor "-3" ist nötig. Siehe "man bash" "Parameter Expansion" Anstatt wie im obigen Beispiel mit einer Schleife zu arbeiten, kann man auch z.B. per sed ein Shell-Script erzeugen und das per Stdin übergeben:
Verzeichnisstruktur am Anfang:
1234/preview_abc.png
1234/abc.png
1234/preview_def.png
1234/def.png
2345/preview_xyz.png
2345/xyz.png

Ziel:
1234/abc.png
1234/def.png
2345/xyz.png
cache/1234/preview_abc.png
cache/1234/preview_def.png
cache/2345/preview_xyz.png
find -name 'preview_*.png' | sed -re 's#^(.*)/(preview_.*)$#mkdir -p cache/\1; mv \0 cache/\1;#'
Ergebnis:
mkdir -p cache/./1234; mv ./1234/preview_abc.png cache/./1234;
mkdir -p cache/./1234; mv ./1234/preview_def.png cache/./1234;
...
Ausführen:
find .. | sed ... | sh -
Oder direkt per -printf von find
# Bilder anhand des Zeitstempels tageweise in Verzeichnisse verschieben:
find -iname '*.jpg' -printf 'mkdir -p %TY-%Tm-%Td; mv %p %TY-%Tm-%Td\n' | bash
   find . -printf '%TY-%Tm-%Td:%TT %p\n' | sort 

   oder einfacher: find -printf '%T+ %p\n' (GNU Extension)

   %T steht für die mtime (Modifikationszeitpunkt). Es kann
   auch %C (Change Time) oder %A (Access Time) verwendet werden.
   Siehe auch "man find" und "man stat"
   
    find . -mtime +0  # Dateien, die älter  als 24 Stunden sind
    find . -mtime  0  # Dateien, die jünger als 24 Stunden sind
    find . -mtime -1  # auch: Dateien, die jünger als 24 Stunden sind
   
Leider kann man mit GNU-find nur nach Dateien mit einem bestimmten Datum suchen, wenn man eine temporäre Datei anlegt:
    #        MMDDHHMM (7. Juli des aktuellen Jahres)
    touch -t 07070000 ~/tmp/start$$
    touch -t 07072359 ~/tmp/end$$
    find -newer ~/tmp/start$$ \! -newer ~/tmp/end$$
    rm ~/tmp/start$$ ~/tmp/end$$
   
Leider gibt es die Option --exclude nicht bei dem Befehl 'find'. Folgendes Beispiel bietet einen Ersatz. Finde alle Dateien, aber überspringe (-prune) Verzeichnisse/Dateien die 'tmp' oder 'temp' heißen:
 # Variante 0: Schlechtes Beispiel: Nur die Ausgabe wird gefiltert. Der
 # Find-Befehl durchsucht aber trotzdem die Verzeichnisse
 find . | grep -vE '/(tmp|temp)/'

 # Variante 1 (Kompatibel zu POSIX find)
 find . \( -name temp -o -name tmp \) -prune -o -print

 # Variante 2 GNU find
 find . -regextype egrep -regex '^.*/(tmp|temp)$' -prune -o -print
Falls der Plattenplatz knapp wird, und man wissen möchte welche Datei und welches Verzeichnis am meisten Platz benötigt, kann folgende Zeile ausführe. Diese Zeile erstellt eine Liste aller Verzeichnisse und Dateien sortiert nach Größe. Falls die Platte (also in diesem Beispiel auch /var/tmp voll) ist, sollte man die Ausgaben ggf. per ssh zu einem anderen Rechner umleiten.
    root> du -ax / | sort -rn > /var/tmp/du-`date --iso`.log

    -x: Bleibe auf diesem Dateisystem. D.h. /proc wird übersprungen. 
    -a: Alle Dateien, nicht nur Verzeichnisse werden angegeben.

    sort -rn: Numerisch absteigend sortieren.


    Falls kein Platz mehr für die Log-Ausgaben sind:

    root@plattevoll> du -ax / | ssh nutzer@woanders -C "sort -rn > /var/tmp/du-`date --iso`.log"
   
Platzverbrauch mit menschenfreundlicher Ausgabe: Die Option -h (human-readable) zeigt bei den folgenden Kommandos die Größe in kByte, Mega-Byte oder Giga-Byte an:
    ls -lh
    --> Größe der Dateien im aktuellen Verzeichnis
   
    du -h
    --> Gesamte Größe inkl. Unterverzeichnisse

    df -h
    --> Platz auf den Dateisystemen/Partitionen
   
find -name '*.py' -print0 | du -b -c --files0-from=-
Neue Versionen des Befehls 'du' kennen die Option --files0-from. Damit lässt sich du Größe von einer Auswahl von Dateien bestimmen. Im obigen Beispiel wird nur die Größe von Python-Scripten berechnet.

Folgendes Beispiel errechnet die Summe der Dateigrößen per awk.
find -name '*.py' -printf '%s %p\n' | awk '{used +=$1}END{print used}'

 -printf %s: Dateigröße
 -printf %p: Pfadangabe (wird in diesem Beispiel ignoriert)
Vergisst man ein Programm im Hintergrund zu starten ("&" am Zeilenende), kann man mit Strg-z das Programm anhalten. Mit den Befehlen "fg" bzw. "bg" kann man das Programm im Vordergrund bzw. im Hintergrund weiterarbeiten lassen.

Trick: Möchte man wissen, wann ein lang laufendes Programm sich beendet, kann man es mit Strg-z anhalten und dann mit folgendem Befehl wieder starten:
    fg ; while /bin/true; do echo -ne \\a; sleep 1; done
   
Nach dem das Programm beendet ist wird in einer Endlosschleife ein Piepgeräusch erzeugt. Während less, vi und emacs "^M" anzeigen, muss man in Scripten die in C übliche Notation "\r" verwenden. Diese kleine Tabelle hilft dabei:
Oct   Dec   Hex   C  
-----------------------------
000    0    00   \0  ^@  NULL (Binäre Null)
007    7    07   \a  ^G  bell
010    8    08   \b  ^H  Backspace 
011    9    09   \t  ^I  Tab
012   10    0A   \n  ^J  Linefeed (newline)
013   11    0B   \v  ^K  Vertical Tab
014   12    0C   \f  ^L  Formfeed
015   13    0D   \r  ^M  Carriage Return
033   27    1B       ^[  Escape

Siehe auch "man ascii" unter Linux.

In der Shell Bash können Controll-Zeichen mittels z.B. $'\t' (bzw. $'\xHH') angegeben werden. Gerade für das Tab-Zeichen ist das in Shell-Skripten sinnvoll, da der Unterschied zwischen Tab und mehreren Leerzeichen nicht zu sehen ist. Siehe "Quoting" in "man bash". Mit dem Programm recode kann den Zeichensatz einer Text-Datei ändern.

Text-Dateien von Unix werden im Notepad auf einer Zeile angezeigt, und Scripte, die mit "#!/bin/interpreter" anfangen laufen nicht unter Unix, da noch ein "Carriage Return" hinten dransteht.
# CR/LF wird zu LF (dos --> unix)
recode latin1/CR-LF..latin1 datei.txt

# und zurück
recode latin1..latin1/CR-LF datei.txt
Die Shell "Bash" hat einen Nachteil. Die meisten Befehle sind nur sehr kurz in der Dokumentation (Siehe "man bash" oder "help befehl") beschrieben. Beispiele sind bei den GNU-Tools leider nicht vorhanden. Darum sind in den folgenden Punkten einige Beispiele aufgeführt. Mit dem Befehl "chmod" werden die Zugriffsrechte einer Datei geändert. Möchte man rekursiv für alle Leserechte hinzufügen, kann man das mit folgenden Aufruf erledigen:
  chmod -R a+rX

   -R rekursiv
   a+ für alle folgende Rechte hinzufügen
   r  Leserecht
   X  Nur für Verzeichnisse: Das Recht, das Verzeichnis aufzulisten (ls)
  
Mit dem Befehl "let" kann man ganzzahlige Berechnungen durchführen:
 i=0
 let "i=i+1"
 echo $i

 # Oder auch so:
 echo $((i+2))
Das heutige Datum im Format YYYY/MM/DD lässt sich leicht ausgeben:
 date +"%Y/%m/%d"
Und mit der GNU Implementierung lassen sich auch leicht andere Tage ausgeben:
 date +"%Y/%m/%d" -d '1 day ago'
Leider ist der Befehl 'date' in der Man-Page zu knapp beschrieben. Diese (-d ...) und andere Details erfährt man mit 'info date'.
echo $(( $(date -u -d2008-04-01 "+%s")/86400 -  $(date -u -d2008-03-31 "+%s")/86400))
Im obigen Beispiel wird die Anzahl der Tage zwischen dem ersten April und dem 31. März berechnet.

Oder mit nimmt eine Programmiersprache, die eine umfangreiche Bibliothek für Datumsberechnungen hat:
 python -c "import datetime; print (datetime.date(2008,4,1)-datetime.date(2008,3,31)).days"
Die Bash unterstützt auch reguläre Ausdrücke. Für einfache Zeichenverarbeitung muss man nicht mehr ein externes Programm (cat, cut, grep, sed, ...) aufrufen. Shell-Builtins sind meist schneller, da häufiges Starten eines Prozesses langsam ist.
if [[ abcfoobarbletch =~ foo(bar)bl(.*) ]]; then
        echo The regex matches!
        echo $BASH_REMATCH      -- outputs: foobarbletch
        echo ${BASH_REMATCH[1]} -- outputs: bar
        echo ${BASH_REMATCH[2]} -- outputs: etch
fi
Siehe Bash in der Wikipedia
Achtung: In der Version 3.2 verhält sich die Bash anders als in 3.0: Der Reguläre Ausdruck darf nicht mehr in Anführungszeichen stehen.
#!/bin/bash

verbose=0
config=/etc/myapp.conf
while getopts c:v o; do
    case "$o" in
        c)      config="$OPTARG";;
        v)      verbose=1;;
        [?])    echo "Usage: $0 [-v] [-c configfile] file ..." >&2
                echo " -v: verbose" >&2
                echo " -c: configfile" >&2
                exit 1;;
    esac
done

shift $((OPTIND-1))
echo "v=$verbose c=$config len-files=$# files: $@"
Durch set -u bricht das Bash-Script ab, falls eine Variable nicht gesetzt ist. Falls man prüfen will, ob eine Variable gesetzt ist, kann man wie folgt vorgehen:
if [ -z "${MYVAR:-}" ]; then
    # Variable MYVAR ist leer, bzw nicht gesetzt.
    ....
fi
Die Befehle "basename" und "dirname" sind wohl allen Shell-Nutzer bekannt. Doch wie kann man eine relative Pfadangabe zu einer absoluten Pfadangabe machen? Mit aktuellen GNU-Tools geht das mit:
 readlink -e ../my/relative/path
Der Vorteil gegenüber $PWD/../my/relative/path: ".." wird aufgelöst.
find / -type l ! -execdir test -e '{}' \; -print

 Erläuterung:

 find /                          Starte find im Wurzelverzeichnis
   -type l                       Suche Symlinks
    ! -execdir test -e '{}' \;   Falls Datei nicht existiert,
        -print                   gebe den Dateinamen aus
Da das Paket pstree nicht immer installiert ist, verwende ich gerne ps aux --forest. Außerdem lässt sich mit ps besser angeben, welche Prozesse angezeigt werden sollen. Eine Übersicht über meine Script-Sammlung: Scripte

Hier eine kleine Auswahl: Abschließend zu dem Kapitel "Shell" einen Hinweis: Mit wenigen Zeilen lassen sich erstaunlich komplexe Probleme lösen. Doch ab etwa 15 Zeilen werden Shell-Scripte meist unübersichtlich und fehleranfällig. Dann sollte man sich die Zeit nehmen und nochmal von vorne mit einer "richtigen" Programmiersprache anfangen. Die meisten Shellscripte funktionieren nicht mehr, falls Leer- oder Sonderzeichen in Dateinamen vorkommen.

Seit 1996 benutze ich fast täglich die Shell interaktiv und in kleinen Scripten. Wenn sich jedoch ein Problem nicht mehr mit find, grep, cut, tr, sort, uniq, sed und perl -lpe lösen lässt, dann verwende ich Python

5 Sonstiges [toc]

Außer der Möglichkeit mittels harten Links (ln datei ziel) ein inkrementelles Backup mit rsync zu machen, gibt es aus meiner Sicht sehr wenige Stellen, an denen harte Links sinnvoll sind.

Symbolische Links (ln -s datei ziel) sind weniger fehleranfällig und lassen sich auf für Verzeichnisse anwenden. SSH (Secure Shell) ist ein Programm um eine sichere Verbindung zwischen zwei Rechnern zu erstellen. "Sicher" im Sinne von "abhörsicher" und "manipulationssicher". Rsync ist ein sehr mächtiges Programm um Dateien zu kopieren. Es werden nur die Änderungen übertragen. Dateien, die auf beiden Rechnern gleich sind, werden übersprungen. Rsync kann mittels ssh, dem eigenen rsync-Protokoll oder lokal benutzt werden.

In der Regel sollte man es vermeiden, einen Rsync-Server aufzusetzen, da es eine unnötige Sicherheitslücke ist. Besser ist es, Rsync mittels ssh zu verwenden. Werden die Daten auf beiden Systemen geändert, sollte man anstatt rsync unison verwenden. Zum Beispiel um einen Laptop und einen PC abzugleichen oder um Software vom Test-System zum produktiven System zu kopieren. Bei den heutigen Preisen für Festplatten lohnt sich ein Streamer für die privaten Daten nicht. Per rsync ein Backup auf eine zweite Festplatte machen:

   mount /dev/hdb2 /mnt/
   rsync -avx --delete-excluded --exclude '/tmp' --exclude '/var/tmp' \
    --exclude '.netscape/cache' \
    --exclude '/var/cache' --exclude '/var/run' --exclude '/var/spool' / /mnt
   
   a: archive-mode (preserve owner...)
   v: verbose
   x: stay on this filesystem (don't backup /proc)
  
Bei einem zweiten Aufruf von rsync werden nur die Änderungen auf die andere Festplatte kopiert.

In Verbindung mit "cp -alr" kann man auch ein mehrere Versionen der Sicherungskopie erstellen. Die Option "-l" erstellt Links anstatt Kopien der Daten, so dass Plattenplatz gespart wird. Siehe auch Rsync Backup. Das Programm "strace" zeigt alle System-Rufe eines Programms an. Es ist somit sehr gut geeignet, um in fremden Programmen Fehler zu finden. Um es sinnvoll einsetzen zu können muss man verstehen was ein System-Ruf (system call) ist. Öffnen von Dateien, schreiben in Dateien oder Sockets, erstellen neuer Prozesse ... sind Systemrufe. Vergleichen von Zeichenketten und Berechnungen sind keine Systemrufe, da dafür keine Funktionen des Betriebssystems nötig sind.

Man kann strace auf ein Programm ausführen (myapp), oder sich mit einem laufenden Prozess verbinden.
  strace myapp
  strace -p PID
  
Meistens verbindet man freie Software mit der Lizenz "GPL". Ich bevorzuge die BSD-Lizenz, da sie kurz und verständlich ist. Außer Richard Stallman, dem Autor der GPL-Lizenz, gibt es sicherlich wenige, die die GPL gelesen und verstanden haben. Mir ist die Zeit dafür zu schade, und bevorzuge deshalb die BSD-Lizenz. Außerdem darf "BSD-Software" auch in kommerziellen Produkten verwendet werden. Die folgenden Punkte beziehen sich auf Linux, bzw. Unix-ähnliche Betriebssysteme.
   Anzeigen der Geräte:
   root> cdrecord -scanbus
   
   Kopie einer Daten CD "on-the-fly" (lesen von /dev/cdrom) (-dummy zum testen)
   root> cdrecord -v dev=0,0,0 -isosize /dev/cdrom 
   
   Löschen eines RW-Rohlings:
   root> cdrecord -v dev=0,0,0 blank=fast 
   
   Mehrfaches brennen einer CD:
     Auslesen:
   
     root> NAME=cd-image
     root> cdrdao read-cd --driver generic-mmc --datafile $NAME.bin  \
      --device /dev/cdrom $NAME.toc
     Schreiben:
     root> cdrdao write --driver generic-mmc \
      --device /dev/cdrom $NAME.toc

   Erstellen und Brennen einer Daten-CD: 

     ISO-Image erstellen:
       (-J ist für Windows-Kompatibilität)

       root> mkisofs -r -J -o my_cd.iso my_dir

       Hinweis: "mydir" ist nicht als Verzeichnis im ISO-Image. Nur
       die Inhalte von my_dir sind enthalten.

     Ggf. Testen des Images:
       root> mkdir /tmp/beispiel && \
       mount -o ro,loop my_cd.iso /tmp/beispiel

     brennen:
       root> cdrecord -v dev=0,0,0  -data  my_cd.iso

   Für DVDs:
    ISO-Image wie oben beschrieben erstellen, dann:
    
    root> growisofs -dvd-compat -Z /dev/dvd=/pfad/myimg.iso
    Falls die DVD schon beschrieben ist, ist ein "blank" nicht nötig.

   Erstellen eines ISO-Images von einer CD/DVD:
    root> readcd dev=/dev/hdc f=/data/images/mydvd.iso
    (readcd ist ein Teil von cdrecord)

   Bei aktuellen Desktop Betriebsystemen (Ubuntu) kann man ISO-Images
   (wenn der Dateiname mit ".iso" endet) einfach durch Anklicken
   brennen.

  
Als Mailserver verwende ich Exim oder Postfix Gute Anleitung für Postfix: Postfix, saslauthd & dovecot imapd/pop3d Howto für Debian sarge 3.1

Das Buch Mit Open Source-Tools Spam & Viren bekämpfen vom o'reilly Verlag ist kostenfrei als PDF verfügbar. Es enthält auch Kapitel für Postfix und Exim.
# mailq per Script auslesen und selektiv Mails löschen
mailq | grep -vE '^-' | while read id; do 
    read msg
    read to
    read leer  
    echo $id $msg $to
done | sed -nre 's/^([^ ]{4,}) *.*EMAILADRESSE$/\1/p' | while read id; do 
    postsuper -d $id
done
DNS (Domain Name Service) ist der Dienst, der Rechnernamen zu IP-Adressen auflöst. Aus "www.google.de" wird dann "66.102.9.99".

Für die wenigsten Netzwerke lohnt es sich mit dem Programm Bind zu arbeiten. Meist spart man sich viel Zeit und Arbeit, wenn man DNSmasq einsetzt. Es ist ein kleiner DNS-Server, der außerdem einen DHCP Dienst anbietet. Die Rechnernamen aus der Datei /etc/hosts werden zur Verfügung gestellt und Anfragen von unbekannten Rechnernamen werden an den Nameserver des Providers weitergeleitet. Der Zeitserver chrony ist sehr flexibel. Er kann sich die Uhrzeit von Zeitservern holen, oder man kann die Zeit per Hand (oder ssh) setzen, falls der Rechner keine UDP Verbindung zu einem anderen Zeitserver aufbauen kann. Cron ist ein Unix-Dienst, der wiederkehrende Aufgaben ausführt. Der Dienst verschickt eine E-Mail an den Nutzer, falls das Script auf stdout oder stderr schreibt. Oft wird deshalb stdout in ein Log-File umgebogen, damit man nicht täglich mit E-Mails "belästigt" wird. Falls eine Warnung auf stderr geschrieben wird, so erhält man trotzdem eine Nachricht. Das Script sollte so geschrieben sein, dass es nur im Fehlerfall auf stderr schreibt, und somit die E-Mail sinnvoll ist. Beim aktualisieren des Linux-Kernels kann man sich leicht ins Knie schießen. Wenn man z.B. keinen Treiber für XFS im Kernel oder in der Initrd hat, jedoch die Root-Partition auf einer XFS Partition liegt hat man schlechte Karten. Das System kann nicht starten.

Das Problem kann man leicht beheben, in dem man ein Disketten-Linux oder Knoppix starten und dann folgende Befehle als root ausführt:
   root@Knoppix> mount /dev/hda1 /mnt
   root@Knoppix> cd /mnt
   root@Knoppix> chroot .     # Ändere das Wurzelverzeichnis!
   root@ill> mount /proc  # Wird von mehreren Programmen benötigt.
   root@ill> mount /sys
  
Nun kann man mit dem System arbeiten, als wäre es normal gestartet. Das auf Debian basierende Ubuntu ist meine bevorzugte Linux Distribution. Ubuntu ist nutzerfreundlich und außerdem ein gutes Betriebssystem für Server. Eine gute Einführung ist der Ubuntuguide.

Die Paketverwaltung mit apt und dpkg ist spielend einfach:
   >apt-cache search "regex"
   Sucht nach "regex" in allen Paketbeschreibungen

   >apt-cache show apache
   Zeigt Paketbeschreibung von Paket "apache" an.
   
   >apt-file "beispiel"
   Sucht nach der Datei "beispiel" in allen installierbaren Paketen.
 
   Alle Pakete die auf "hold" stehen zu "install" machen, damit
   sie beim nächsten "apt-get upgrade" aktualisiert werden:
   root> dpkg --get-selections > /tmp/selections
   root> cat /tmp/selections | sed 's/hold$/install/' | dpkg --set-selections 
   

   >dpkg -L beispiel
   Zeige die Liste der installierten Dateien des Paketes "beispiel".

   >dpkg -S /etc/beispiel
   Sucht das Paket zu dem die Datei "/etc/beispiel" gehört. Es wird dabei nur nach installieren Paketen gesucht.

   Achtung, der Slash am Ende ist von Bedeutung:
     # dpkg -S /etc/ssh           
     ssh: /etc/ssh

     # dpkg -S /etc/ssh/
     dpkg: /etc/ssh/ nicht gefunden.

   >dpkg-query ... ähnliche wie dpkg, es wird aber in den installierten und nicht installierten Paketen gesucht. 
   Siehe Debian Anwenderhandbuch
  
Debian-Pakete unter einer anderen Distribution auspacken:
 ar tv beispiel.deb # Anzeigen des Inhalts
 ar xv beispiel.deb # Auspacken
Der Befehle "ar" ist auf allen Unix-System verfügbar. Möchte man an die Daten, ohne das Paket zu installieren, so kann man eine RPM Datei wie folgt auspacken:
   -Archiv entpacken:
  mkdir wvware
  cd $_
  rpm2cpio ../wv-0.7.2-189.src.rpm | cpio -id

  cpio: -i: extract, -d: create directories 

 
Wie bekommt man heraus zu welchem Paket die Datei "beispiel" gehört?
  rpm -qf /usr/bin/tex
 
Informationen über ein Paket
  rpm -qi beispiel
 
Dateiliste eines Pakets:
  rpm -ql gcc
 
Hier eine Liste von Paketen, die ich normalerweise immer installiere: pakete.txt Eine DVD oder CD kann man erst herausholen, wenn sie aus dem Unix-System entfernt wurde. Das aushängen (umount) ist aber nur möglich, wenn kein Prozess mehr das Dateisystem benötigt. Leider teilt der Befehl nicht mit, welche Prozess das Dateisystem noch benötigt. Falls man "lsof" installiert hat, kann man das wie folgt herausbekommen:
 # ggf. als root aufrufen, damit man alles sieht.
 lsof | grep /media/dvd

 # oder
 fuser -u /media/dvd
Falls "lsof" nicht installiert ist:
for file in /proc/[0-9]*/cwd /proc/[0-9]*/fd/* ; do echo $file `readlink $file` ; done | grep /media/dvd
Eine Socket-Verbindung wird vom Client zum Server aufgebaut. Mit dem Programm "telnet" kann man zu jedem Port eines Servers einen Verbindungsaufbau mit einem TCP-Socket versuchen.

Protokolle wie SSH, POP3, SMTP, HTTP verwenden TCP für die Kommunikation zwischen Client und Server.
SMTP (RFC 821):
2xx = OK
5xx = Fehler

telnet mails-server 25
ggf. (M$ IIS): EHLO client-rechner

[AUTH PLAIN ???]

Die Zeichenkette für "???" erhält man mit:
perl -MMIME::Base64 -e 'print encode_base64("username\0username\0password");'
  (Siehe Postfix SASL README)


mail from: <email@me.de>
rcpt to: <user@blu.de>
data
Subject: Hallo!

das ist der Body der Email
. (Zeile mit nur einem Punkt beendet die Email)
quit
POP3 (RFC 1725):
telnet mail-server 110
user <name>
pass <passwort>
list (Anzeige der Emails)
retr <nummer> (Email anzeigen)
dele <nummer> (Email löschen)
[top <msg> <N> (Optionaler
   Befehl (wird von den meisten POP3-Servern implementiert: Anzeigen der ersten N Zeilen)]
quit

HTTP (RFC 2616):
telnet www.beispiel.org 80
GET url HTTP/1.0

(Zweimal Return)

url: / bzw. /beispiel.html

HTTP... kann ggf. weggelassen werden

Da viele Webserver mit "namebased virtual hosts" arbeiten, muss man
dem Webserver noch mitteilen, unter welchem Namen man sich mit ihm
unterhält:
telnet www.beispiel.org 80
GET url HTTP/1.1
Host: www.beispiel.org

 
Noch ein Hinweis zu Telnet: Wenn man mit telnet auf einen Portzugreift, und die Verbindung nicht mit protokollspezifischen Befehlen wie "quit" beenden kann, kann man mit Strg-] die Sitzung unterbrechen und die Verbindung konfigurieren. Unter der URL dict.tu-chemnitz.de gibt es ein sehr umfangreiches Deutsch-Englisches Wörterbuch. Im Gegensatz zu dem bekannten Wörterbuch von LEO kann man das der Chemnitzer Uni herunterladen. In der 4,7 MByte großen Datei kann man schnell mit seinem Editor der Wahl nachschlagen. Eine Internetverbindung ist nach dem Herunterladen nicht mehr nötig. die AVIs meiner Digitalkamera (Canon Powershot S80) sind sehr groß. Mit folgender Kommandozeile verkleiner ich die Dateien. Es sind zwei Aufrufe von mencoder. Beim ersten Durchgang wird lediglich die Datei divx2pass.log erzeugt. Mit dieser Datei kann im zweiten Durchlauf eine verbesserte Komprimierung erfolgen.
mencoder MVI_1234.AVI -oac mp3lame -ovc xvid -xvidencopts pass=1 -srate 8000 -o /dev/null
mencoder MVI_1234.AVI -oac mp3lame -ovc xvid -xvidencopts pass=2:bitrate=1200 -srate 8000 -o klein.avi
Siehe auch Gentoo Wiki. Folgende Programme und Technologien sind weit verbreitet, jedoch gibt es moderne, bessere und ggf. kostengünstigere Alternativen:
Bisher / Standard Besser Begründung
Sendmail Exim oder Postfix Weniger Altlasten im Quelltext. Sicherer und leichter zu konfigurieren.
Fetchmail getmail Getmail ist nicht in C geschrieben, sondern in Python. Sicherheitslöcher wie bei Fetchmail sind unwahrscheinlich.
Procmail Sieve Die Syntax der Konfiguration von Procmail ist unnötig kompliziert. Sieve ist eine einfache Programmiersprache um Emails zu filtern. Es gibt mehrere Implementierungen. Der größte Vorteil ist, dass das Filtern schon auf dem Server passieren kann, so dass die Emails in verschiedene (meist IMAP) Ordner abgelegt werden.
MBox Format maildir Bei Maildir wird pro Email eine Datei gespeichert. Es gibt keine Probleme beim Locking, falls mehrere Prozesse auf die Emails zugreifen. Siehe auch Maildir im Dovecot Wiki.
Cyrus (IMAP/POP3 Server) Dovecot Dovecot ist leichter zu konfigurieren und zu verstehen.
Perl Python Siehe Warum ich von Perl zu Python gewechselt bin.
tcl/tk pyGTK Die Programmiersprache tcl und das Toolkit tk werden kaum weiterentwickelt.
telnet OpenSSH Bei Telnet werden Passwörter im Klartext übertragen.
tail -f less +F Der Vorteil von Less ist, dass das fortlaufende Lesen der Datei abgebrochen werden kann, und man z.B. nach bestimmten Zeilen suchen kann.
IPSec OpenVPN OpenVPN ist einiges einfacher und verträgt sich besser mit Firewalls.
Debian Ubuntu Während Debian nur von Freiwilligen entwickelt wird, wird das auf Debian aufbauende Ubuntu durch bezahlte Entwickler verbessert.
fvwm2 Xfce KDE und Gnome sind für alte Rechner zu langsam. Xfce ist vielleicht nicht ganz so klein wie fvwm, dafür aber einiges komfortabler und leichter zu konfigurieren.
fdisk cfdisk Das Programm fdisk ist jedem bekannt. Unter DOS gab es ein Programm mit dem gleichen Namen. Doch cfdisk lässt sich einiges einfacher verwenden (auch leichter als fdisk von Linux).
Oracle, MySQL PostgreSQL PostgreSQL ist eine robuste relationale Datenbank. Sie wird seit mehr als 15 Jahren weiterentwickelt und unterstützt die Standards SQL92 und SQL99.
Hardware RAID Software RAID Bei modernen Servern spielt der Mehraufwand der CPU keine Rolle
Siehst du den Unterschied?
user@host> su
Passwort: 
root@host:/home/user# /etc/init.d/apache restart
user@host> su -
Passwort: 
root@host:~# /etc/init.d/apache restart
Lösung:
'su' ohne Bindestrich übernimmt die Umgebung des Nutzers. Das heißt $HOME, $PATH, ... werden vom Nutzer übernommen. Das kann scheinbar nicht erklärbare Veränderungen für alle von Apache gestarteten Kindprozesse (CGI-Scripte) haben.

6 Programmiersprachen [toc]

Meine bevorzugte Programmiersprache: Siehe Python Einführung

6.2 Perl Einzeiler [toc]

GNU Tools (grep, sed, awk, ...) kennen leider keine PCRE (Perl Compatible Regular Expressions).
Suchen und Ersetzen mit Perl:

perl -pi -e 's/etwas/soetwas/g' datei1 datei2 ...

 -p: Für jede Zeile in den Dateien
 -i: Inplace: Ersetze die Dateien durch die neuen Zeilen
     mit -i.orig werden die alten Dateien zu datei.orig umbenannt
 -e: Expression (Perlbefehle)

Siehe auch Linux Server Hacks (o'reilly)

 Perl als Ersatz für sed:

 echo $'zeile1\nzeile2' | perl -lpe 's/^(\w+)(\d+)$/\2 \1/'

 -l: Hänge an die Ausgaben ein Newlinezeichen an
 -p: Die Anweisung für jede Zeile ausführen
 -e EXPR: Perlanweisung

 sed -ne 's/.../.../p' (Falls Ausdruck nicht passt, Zeile ignorieren)

 echo $'zeile1\nmist\nzeile2' | perl -lne 's/^(\w+)(\d+)$/\2 \1/ && print'

 Damit die Ausgabe nicht zeilenweise, sondern auf einer Zeile erfolgt,
 'print' durch 'printf' ersetzen.

Siehe auch: Perl one-liners
und man perlrun Das Programm "make" aktualisiert eine Datei, wenn sich die Quelldatei geändert hat. Make benutzt dafür die "mtime" (Zeitpunkt der letzten Änderung) der Datei.

Folgendes Makefile erstellt aus Gimp-Dateien (.xcf) kleine PNG-Dateien, so bald sich die Gimp-Datei ändert. Der Trick an diesem Makefile ist, dass die Quelldateien nicht aufgelistet werden. Es werden alle *.xcf Dateien des aktuellen Verzeichnisses zu PNG-Dateien gewandelt.
INPUT_FILES := $(wildcard *.xcf)
OUTPUT_FILES := $(INPUT_FILES:.xcf=.png)

all: $(OUTPUT_FILES)

%.png: %.xcf Makefile
        convert -geometry 50x -background '#eee2b4' $< $@

clean:
        rm -f $(OUTPUT_FILES) *~

7 Web-Design und Web-Entwicklung [toc]

8 X-Windows [toc]

XFree86 ist eine grafische Oberfläche für Linux. X ist netzwerkfähig. D.h. ein Programm, das auf Rechner A läuft kann seine Ein- und Ausgabe über Rechner B erledigen. So kann man z.B. mit einem alten 486er im Internet surfen, während der resourcenhungrige Browser auf einem anderen Rechner läuft. XFree86 ist inzwischen auch für Windows verfügbar (XFree Cygwin).

9 Cygwin [toc]

Cygwin ist Unix für Windows. Es beinhaltet alles was man braucht: Shell (Bash), grep, ls, cd, ... Sogar ein X-Server ist dabei. Es ist open source Software.

10 XML [toc]

Diese Beschreibungssprache ist für den standardisierten Datenaustausch wichtig. XML hat jedoch nichts mit Web-Browsern und HTML zu tun. Webbrowser werden in Zukunft weiterhin HTML darstellen. SAX und DOM sind zwei verschiedene Konzepte um mit einer Programmiersprache XML zu verarbeiten.

SAX steht für "Simple API for XML". Ein SAX-Parser (meist expat) liest eine XML-Datei und ruft für jedes öffnende und schließende XML-Tag eine vom Anwender definierte Funktion auf.

Bei DOM wird eine Baumstruktur aus der gesamten XML-Datei aufgebaut. Meist wird dieser Baum mittels SAX erstellt. Der Anwender kann dann die Objekte der Baumstruktur bearbeiten.

Wann SAX, wann DOM?
Weiter Begriffe der "XML-Welt": Um XML gibt es eine Unzahl von Standards, die größtenteils nicht praxisrelevant sind: XLink, ....

11 Persönliche Meinung [toc]

12 Leseempfehlungen [toc]

13 About [toc]

Diese Seite wurde von mir vorgetragen:
© 2003-2006 Thomas Güttler. Der Text darf nach belieben kopiert und modifiziert werden, solange dieser Hinweis zum Copyright und ein Links zu dem Original unter www.thomas-guettler.de erhalten bleibt. Es wäre nett, wenn Sie mir Verbesserungsvorschläge mitteilen: guettli@thomas-guettler.de
Schreiben Sie mir doch eine E-Mail, falls Ihnen die Seite gefallen/geholfen hat. Falls Ihnen die Seite sehr gut gefällt, wäre ein für Google auffindbarer Link hierher nett.