/
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
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]
2.1 Allgemein
[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.
2.2.1 Software RAID
[toc]
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.
2.3 hdparm
[toc]
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?
2.4.1 Einführung
[toc]
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.
2.4.2 Beispiele
[toc]
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".
2.4.3 Eine Partition wurde gelöscht: Grub Error 22
[toc]
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?
- 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.
- 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.
- Die Datei "/etc/fstab" anpassen.
- 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.
- Live-CD entfernen, Neustarten und hoffen, dass das System wieder
startet.
3 Interaktive Programme
[toc]
3.1 Readline / Bash
[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.
3.2 Editor
[toc]
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
3.5.1 Mutt
[toc]
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
3.5.2 Thunderbird
[toc]
Der Email Client Thunderbird
läuft unter Windows, Linux und vielen anderen
Betriebssystemen. Folgende Plugins verwende ich:
- Nostalgy:
Mit diesem Plugin lassen sich Shortcuts definieren, um
Thunderbird besser mit der Tastatur (anstatt der Maus) bedienen zu
können.
- Sieve: Mit diesem Plugin
lassen sich Sieve Scripte leicht auf dem Server editieren/installieren/aktivieren.
- Redirect (Bounce):
Nachdem man einen Sieve Filter angelegt hat, will man wissen ob
der IMAP-Server die Emails nun richtig einsortiert. Mit diesem
Plugin kann man Emails unverändert (also nicht wie beim
Weiterleiten oder Antworten) z.B. an sich selbst
weiterschicken. Wenn das Sieve Script richtig funktioniert, landet
die Kopie in dem entsprechenden Ordner.
Ein großer Nachteil: Thunderbird unterstützt bis jetzt nicht das Maildir Format.
3.5.3 Maildir
[toc]
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
3.5.4 getmail
[toc]
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:
- Die Emails werden direkt in die Mailbox geschrieben. Ein
SMTP-Server ist nicht nötig.
- getmail ist in Python geschrieben. Kleine Anpassungen sind
leicht möglich.
- Fetchmail und Procmail sind in C geschrieben, so dass
Buffer-Overflows und somit Sicherheitslücken wahrscheinlich sind.
- Fetchmail arbeitet mit zu vielen Protokollen. Das macht den
Code und die Dokumentation unübersichtlich.
- Die Syntax von procmailrc und fetchmailrc Dateien ist unschön.
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
3.7 Bildbearbeitung
[toc]
3.7.1 Gimp
[toc]
Gimp ist ein Bildbearbeitungsprogramm (eine Alternative zu
Photoshop). Es ist auch für Windows verfügbar.
- ALT+SHIFT während dem Verschieben verschiebt nur
die "Selection" aber nicht das Bild in der Selektion.
- Eigene eigenen Pinsel erstellen: Als .gbr abspeichern in
$HOME/.gimp??/brushes und Gimp ggf. neu starten.
- Linien zeichnen: Mit Pinsel oder Stift malen und Shift-Taste
halten.
- Füllen von transparentem Hintergrund: Markieren,
Bearbeiten/Füllen
- Mit transparenter Farbe malen (Alphakanal bearbeiten): Im
Ebenen-Dialog die gewünschte Ebene markieren. Rechte Maustaste
--> "Ebenenmaske hinzufügen" (ggf. vorher Alphakanal
hinzufügen). Und dann "Alphakanal der Ebene übernehmen". Für die
Ebene gibt es nun zwei Vorschaubilder (im Ebenen-Dialog), die man
einzeln selektieren kann. Wählt man die Ebenenmaske, dann malt
schwarze Farbe den Bereich transparenter und weiße Farbe macht
den Bereich deckender.
Siehe auch Ebenenmaske
im Handbuch
- Rotieren um beliebigen Winkel: Kontext Menü / Werkzeuge / Transformationen / Transformation
- Farbe zu Transparenz: Kontexmenü / Filter / Farben / Farbe
nach Transparenz
- Rote Augen entfernen:
- Mit der Lupe die Augen 'ranzoomen'.
- Doppelklick auf Freihand-Auswahl
- Ausblenden einstellen
- roten Bereich markieren (Shift-Klick, beim zweiten Auge, damit erster Bereich nicht verloren geht)
- rechte Maustaste: Werkzeuge / Farben / Farbton-Sättigung
- Helligkeit und Sättigung nach links ziehen.
- Anschließend ggf. Lichtreflex in den Augen mit dem Stempelwerkzeug aufhellen. (Mit strg-Klick den weißen Bereich neben der Iris wählen. Pinsel auf 1x1 Pixel stellen)
Siehe auch:
gimp-rote-augen
- Crop per Tastatur: Shift-c, Ausschnitt wählen, dann Enter drücken.
- Deutschsprachiges Benutzerhandbuch
3.7.2 Bilder sortieren
[toc]
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]
3.7.3 ImageMagick und NetPBM
[toc]
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:
- Bild zu der Auflösung von 1024x768 konvertieren:
convert -geometry 1024x768 beispiel.jpg beispiel_1024.jpg
- Bild-Datei zu Postscript konvertieren (zum Drucken):
convert beispiel.jpg ps2:beispiel.ps
"ps2:" ist sinnvoll, ansonsten wird die Datei um ein vielfaches größer,
da Postscript Level 1 verwendet wird.
-
Da manche PNG-Bibliotheken fehlerhaft sind, sollte man beim
Erstellen von schwarz-weißen PNG-Dateien folgende Optionen
angeben. Nötig für alten Konqueror und alten Netscape (4.7)
convert -map netscape: -background black datei.tiff datei.png
-
Die Größe eines Bildes auslesen:
identify -format "%w %h"
- Die von Anthony Thyssen erstellte Beispielsammlung (ImageMagick
Examples) ist sehr zu empfehlen.
NetPBM:
3.7.4 Von der Kamera ins Dateisystem
[toc]
- Bilder von dern Kamera holfen
gphoto2 --get-all-files
- Bilder anhand der Exif-Orientierung drehen
find -iname '*.jpg'| xargs exiftran -aip
- 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.
3.8 FTP-Client
[toc]
Ich bin ncftp sehr zufrieden. Er kann auch nicht interaktiv (in
Shell-Scripten) verwendet werden: ncftpput, ncftpget.
3.9 Screen
[toc]
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:
- Strg-z -->> Prozess unterbrechen
- bg --> Prozess im Hintergrund schicken
- disown -h %1 --> Prozess von der Shell abkoppeln und immun gegen SIGHUP machen.
- logout --> Aktuelle Shell kann beendet werden, und Prozess läuft trotzdem weiter.
3.10 Packer
[toc]
3.10.1 Zip
[toc]
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
3.10.2 TGZ
[toc]
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
3.10.3 BZip2
[toc]
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.
3.11 Openoffice.org
[toc]
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.1 Allgemein
[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.
4.2 Startdateien
[toc]
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.
- ~/.bash_profile:
# ~/.bash_profile: executed by bash(1) for login shells.
#Setze Titel von xterm.
st=$HOME/scripts/settitle.sh # thomas-guettler.de/scripts/settitle.sh
if [ -x $st ]; then
$st $USER@$HOSTNAME
fi
# keychain: Zum Beispiel für SSH-Agent für Cronjobs
keychain --noask ~/.ssh/id_rsa
. ~/.keychain/${HOSTNAME}-sh
. ~/.bashrc
- ~/.bashrc:
# ~/.bashrc: executed by bash(1) for non-login shells.
# Ich finde folgende Prompt praktisch.
# Vorteil 1: "===>" findet man leicht, wenn man
# mehrere Seiten im xterm zurückblättert.
# Vorteil 2: Da das aktuelle Verzeichnis in der ersten
# Zeile und der Cursor auf der zweiten, steht der Cursor
# immer an der gleichen Stelle
if [ "$PS1" ]; then
if [ "$USER" = "root" ]; then
striche="###"
else
striche="==="
fi
PS1="\u@\h:\w\n${striche}> "
fi
if [ "$PS1" ]; then
# C-w nicht vom Terminal verarbeiten,
# sondern per .inputrc zu kill-region mappen
stty werase ''
fi
# Per Default Leserechte für alle.
# 022 entspricht "chmod 755" oder "chmod a=rX,u+w"
# Für Verzeichnisse: drwxr-xr-x
# Für Dateien: -rw-r--r--
umask 022
# Das Software, die man mit prefix=$HOME installiert ist in $HOME/bin.
# Meine Scripte sind in $HOME/scripts
PATH="$HOME/bin:$HOME/scripts:${PATH}:.:/usr/sbin:/sbin"
# History der Bash (zurückblättern) soll lang sein.
# Default von 500 Zeilen ist zu wenig.
# HISTSIZE: Anzahl der Zeilen im Speicher
export HISTSIZE=50000
# HISTFILESIZE: Anzahl der Zeilen in der Datei
export HISTFILESIZE=50000
# Schreibe die eingegebenen Befehle sofort und
# mit Zeitstempel in die History
export PROMPT_COMMAND="history -a"
export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S : "
#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
#Deutscher Zeichensatz, aber Fehlermeldungen
#sollen auf englisch sein:
export LC_CTYPE=de_DE
- ~/.inputrc
#~/.inputrc fuer readline Bibliothek
# Änderungen an dieser Datei können mit C-x C-r eingelesen werden.
#Kein Piepsen!
set bell-style visible
#Case insensitiv file completion (TAB-Taste bei Befehlen/Dateien)
set completion-ignore-case on
# C-SPACE C-w: Bereich ausschneiden
# C-SPACE M-w: Bereich in Kill-Ring kopieren
# C-y : Bereich einfügen
# "bind -p" gibt die aktuelle Tastaturbelegung aus.
# Achtung: "stty erase ''" ist .bashrc nötig, sonst wird C-w
# vom Terminal abgefangen.
"\C-w": kill-region
"\M-w": copy-region-as-kill
# Bei einem Symlink zu einem Verzeichnis,
# nicht auf ein zweites TAB warten, sondern
# gleich den Slash anhängen.
set mark-symlinked-directories on
set show-all-if-ambiguous on
Grep verwendet Reguläre Ausdrücke um Zeilen in der Textdatei zu
finden.
-
find . | grep -E '\.(txt|html)$'
-E: Extended Regular Expression
findet alle Dateien ab dem aktuellen Verzeichnis, die mit .txt oder
.html enden ($ == Ende). Symlinks werden nicht aufgelöst.
-P (Perl Compatible Regular Expression. Wird meist leider nicht unterstützt)
-
grep -rsiEI '[^f]xform' .
-r: Rekursiv
-s: silent (Keine Fehlermeldung falls "permission denied")
-i: Case-Insensitiv (kein Unterscheidung zwischen Groß- und
Kleinschreibung)
-I: Durchsuche nur Text-Dateien, keine binären Dateien.
-E: Extended Regular Expression: "(" für Gruppierungen, "|" für "oder"
-
grep -r --include '*.txt' abcde .
--include: Durchsuche nur Dateien auf die das Glob-Muster passt (Siehe auch "man 7 glob")
- Bestimme Prozesse killen:
> kill $(ps aux | grep '[g]pg-agent'| tr -s ' ' ' ' | cut -d ' ' -f2)
- ps aux: Alle Prozesse anzeigen
- grep: gpg-agent, aber nicht den eigenen grep-Prozess anzeigen
- tr -s ' ' ' ': Mehrfache Leerzeichen durch eins ersetzen
- cut -d' ' -f2: Nur die zweite Spalte ausgeben
- kill $(...): Das Ergebnis des geklammerten Ausdrucks sind Prozess-IDs. Diesen Prozessen
das Signal SIGTERM senden.
- Alle nicht druckbaren Zeichen ersetzen:
> befehl-mit-ausgabe-auf-stdout | tr -c '\n\040-\176' '\n~'
siehe "man ascii"
\040 ist oktal SPACE
\176 ist oktal ~
-c Komplementär von MENGE1
UTF8 Zeichen machen bei grep ggf. Unschöne Umbrüche: (Umlaut Ä)
Die Ã
nderung
--> Die ~~nderung
4.5 Schleife
[toc]
4.5.1 Allgemein
[toc]
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.
4.5.2 Dateien umbenennen
[toc]
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".
4.5.3 Dateie verschieben
[toc]
Nur eine Auswahl an Dateien in ein Zielverzeichnis verschieben:
find ... -print0 -name '*.png' | xargs -0 mv --target-directory mydir
4.6 mystring.endswith("beispiel") in der Bash
[toc]
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"
4.6.1 Per sed ein Shell Script erstellen
[toc]
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
4.7 Ausgaben zusätzlich in eine Datei umleiten
[toc]
4.8 Dateien nach Zeitstempel sortieren (inkl. Unterverzeichnisse)
[toc]
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"
4.9 Dateien, die älter als 24 Stunden sind finden
[toc]
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
4.10 Dateien eines bestimmten Datums finden
[toc]
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$$
4.11 find --exclude
[toc]
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
4.12 Plattenplatzverbrauch
[toc]
4.12.1 Liste aller Verzeichnisse/Dateien sortiert nach größe
[toc]
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"
4.12.2 Man spricht menschlich
[toc]
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
4.12.3 Gesamte Größe bestimmter Dateien.
[toc]
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)
4.13 Mehrere Jobs
[toc]
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.
4.14 Control-Zeichen
[toc]
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".
4.15 Recode
[toc]
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
4.16 Fehlende Beispiele
[toc]
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.
4.16.1 chmod
[toc]
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)
4.16.2 Rechnen mit der Shell
[toc]
Mit dem Befehl "let" kann man ganzzahlige Berechnungen durchführen:
i=0
let "i=i+1"
echo $i
# Oder auch so:
echo $((i+2))
4.16.3 Rechnen mit Datumsangaben
[toc]
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'.
4.16.4 Anzahl der Tage zwischen zwei Datumsangaben
[toc]
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"
4.16.5 Reguläre Ausdrücke
[toc]
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.
4.16.6 getopts: Parameter auslesen
[toc]
#!/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: $@"
4.16.7 set -u
[toc]
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
4.17 abspath
[toc]
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.
4.18 Defekte Symlinks finden (Find broken symlinks)
[toc]
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
4.19 Prozesse
[toc]
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.
4.20 Scripte
[toc]
Eine Übersicht über meine Script-Sammlung: Scripte
Hier eine kleine Auswahl:
- kill-regexp.pl: Beende Prozesse, auf die ein regulärer Ausdruck passt.
- my-html-tidy.sh: Überprüfe HTML-Seiten mit tidy, ignoriere dabei unnötige Warnungen.
- number-html-headings.py: Nummeriere HTML-Seiten entsprechend der <h?> Tags. Erstelle ggf. eine Inhaltsangabe.
- reprec.py:
Rekursives Ersetzen. Kann mit und ohne regulären Ausdrücken
verwendet werden.
- settitle.sh: Eine spezielle echo-Anweisung ändert den Titel eines xterms. Bei mehreren xterms auf einem Desktop, kann man so schnell zu einem bestimmten xterm wechseln.
4.21 Wann nimmt man eine "richtige" Programmiersprache?
[toc]
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]
5.1 Vermeide "harte Links"
[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".
-
Da scp die Login-Dateien wie z.B. .bashrc ausführt, darf in
diesen Dateien keine Ausgabe nach stdout geschehen. Die Ausgabe
sollten nach stderr umgeleitet werden:
echo "bla" >&2
- X-Forwarding:
beispiel@here> ssh -X user@server
user@server> xeyes ---> Anzeige der xeyes auf dem lokalen Rechner, Programm
läuft jedoch auf dem entfernten Rechner.
- SSH über Hops. Kommt man von Rechner C zu S nur über Rechner M, so
hilft folgende .ssh/config Datei (C --> M --> S):
Host S
ProxyCommand ssh M netcat -w 5 S 22
#ssh/scp nun direkt von C zu S möglich.
Hinweis: Das Programm netcat muss auf dem Rechner M installiert sein.
- Mit "scp -r" ist es leider nicht möglich nur bestimmte Dateien
zu übertragen. Das ist auch nicht nötig, weil man mit zwei
Tar-Befehlen arbeiten kann. Das "tar" auf dem entfernten Rechner
schreibt nach stdout und das "tar" auf dem lokalen Rechner liest von
stdin. Beispiel:
# Beispiel 1: Dateien von remotehost holen:
ssh remotehost "cd beispiel; find . -name '*.jpg' | tar -cf - --files-from=-" | tar -xvf -
# Beispiel 2: Dateien zu remote host kopieren:
# Aus dem Verzeichnis "workdir" wird das Verzeichnis "beispieldir" kopiert.
cd workdir
find beispieldir -name "*.txt" | tar -cf - --files-from=- | ssh remotehost tar -xvf - -C workdir
-
Startet man in einer SSH-Session ein Programm, das nach Beenden der
Session weiterhin aktiv ist (z.B. mit dem Befehl "nohup" ohne
schließen von stdin mit "</dev/null"), kann man die SSH-Sitzung
nicht beenden. Nach dem Logout (bzw. Strg-D) bleibt die Shell
offen. Wie folgt kann man nun vorgehen:
RETURN ~ h --> Hilfe: Zeigt die Befehle die SSH versteht
RETURN ~ . --> Beendet die aktuelle Sitzung
RETURN ~ & --> Schickt die SSH-Sitzung in den Hintergrund.
- Portforwarding ist einfach und praktisch. Um einen Port vom
lokalen Rechner zu einem entfernten weiterzuleiten wird die Option
"-L" verwendet:
Zwei Rechner:
hier --- entfernt
nutzer@hier> ssh -L 8888:localhost:80 entfernt
Die Secure Shell baut eine Verbindung zu dem Rechner
"entfernt" auf und leitet von dort localhost:80 weiter zu dem
Rechner "hier". Anschließend kann man mit "telnet localhost 8888"
auf dem Rechner "hier" testen, ob die Verbindung besteht. Merke: Der
Hostname zwischen den Doppelpunkten wird auf dem Rechner "entfernt"
aufgelöst.
Vier Rechner:
hier2 --- hier --- entfernt --- weit-weg
nutzer@hier> ssh -g -L 8888:weit-weg:80 entfernt
Wie oben, bloß dass von dem Rechner "entfernt" der Port von
"weit-weg" weitergeleitet wird. Mit der Option "-g" (Gateway) ist es
anderen Rechnern möglich, den weitergeleiteten Port auf dem Rechner
"hier" anzusprechen. Eine Verbindung mit "telnet hier 8888" vom
Rechner "hier2" ist nun möglich.
Die Fehlermeldung "bind: Address already in use" kann ignoriert
werden. Sie kommt angeblich davon, dass SSH versucht auf IPv4 und
IPv6 Ports lauschen.
- Fehlersuchen beim SSHD: Falls der SSH-Server sich nicht so
verhält wie er soll, und man möchte z.B. mehr Debug-Meldungen
sehen, kann man einen zweiten Server auf einem anderen Port
starten. Das ist insbesondere sinnvoll, falls man gerade per SSH
eingeloggt ist, und man nicht den Zugang für andere während dem
Testen stören will. Gerade bei weit entfernten Server muss man beim
Bearbeiten der SSHD Konfiguration sehr vorsichtig sein.
/usr/sbin/sshd -d -e -p 2222
-d Debug
-e Log nach stderr
-p Anderer Port (richtiger Server läuft weiterhin auf 22)
Es startet ein SSH-Server auf Port 2222. Mit einem Client kann man
sich nun, mit der zusätzlichen Option "-p 2222" mit diesem Server
verbinden.
Man kann auch mit "-f" dem Debug-Server eine andere
Konfigurationsdatei geben. Mit dieser Konfigurations kann man dann
"spielen" und den richtigen Server erst neustarten, falls die Tests
erfolgreich waren.
Achtung: Der mit "-d" gestartete Server beendet sich nach einer
Verbindung wieder.
-
NTP für Arme. Lohnt sich der Einsatz von NTP (Network Time
Protocol) nicht, oder ist ein Rechner nur per TCP und nicht per
UDP erreichbar, dann hilft folgender Aufruf, um die Uhrzeit auf
einem entfernten Rechner zu setzen:
ssh root@weitweg date -s \"`date -R`\" \; hwclock --systohc
"date -R" wird auf dem lokalen Rechner ausgeführt. Die Option "-R"
bewirkt, dass eine Ausgabe erzeugt wird, die der entfernte Rechner
auch versteht. Die Ausgabe von Date ohne Optionen ("Mi Dez 14
20:16:05 CET 2005") wird aufgrund der deutschen Schreibweise auf
dem entfernten Rechner ggf. nicht verstanden. Mit "date -s" wird
auf dem entfernten Rechner das Datum gesetzt.
- SSH Public Key für passwortfreies Anmelden installieren:
cat ~/.ssh/id_rsa.pub | ssh remote-rechner "mkdir -p .ssh; cat >> .ssh/authorized_keys"
Für diesen SSH-Aufruf muss man das Passwort noch ein letztes Mal eingeben.
- Zugriff auf mit Passphrase geschützte Schlüssel aus einem Cron-Job:
Mit dem Programm "ssh-agent" werden die Umgebungsvariablen
gesetzt, so dass man mit allen Kind-Prozessen die Schlüssel
benutzen kann. Doch ein Cron-Job läuft zwar mit der User-ID des
Nutzers, hat aber keinen (direkten) Zugriff auf die nötigen
Umgebungsvariablen. Mit dem Script keychain werden
die nötigen Informationen unter $HOME/.keychain/${HOSTNAME}-sh
gespeichert.
- SSH
Filesystem. Mit aktuellen Linux-Systemen, können Dateisysteme
auch von normalen Nutzern eingebunden werden (FUSE). Mit
folgender Crontabzeile wird nach jedem Neustart automatisch ein
Verzeichnis von einem entfernten Rechner eingebunden:
# crontab des lokalen Nutzers
@reboot sshfs -o reconnect nutzer@remotehost:dir localdir
Besonders praktisch finde ich sshfs um anschließend mit Unison zwei Verzeichnisse abzugleichen. Das hat den Vorteil, dass auf dem Remotehost Unison nicht installiert sein muss. Folgendes sollte man dabei beachten:
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.
5.3.1 Backup auf andere Platte
[toc]
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.
5.4 strace
[toc]
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
5.5 Open Source Software Lizenzen
[toc]
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.
5.6 Netzwerke
[toc]
Die folgenden Punkte beziehen sich auf Linux, bzw. Unix-ähnliche
Betriebssysteme.
-
Meine beliebtesten Optionen für netstat:
-l Zeige Sockets die an einem Port lauschen (Server)
-a Zeige alle (lauschende und verbundene) Sockets.
-Ainet nur tcp/udp nicht unix sockets. Entspricht -tu
-n Numeric (Port und Rechnernamen als Zahlen anzeigen)
-p Zeige die PID und den Programmnamen in jeder Zeile.
Mehr über den Prozess kann man in dem Verzeichnis /proc/PID/ erfahren.
Nur der Nutzer root kann die PID von anderen Nutzern sehen.
-e Erweiterte Informationen (Nutzername, Inode)
Bsp:
Welche Server lauschen auf welchen Ports? (Per Inted gestartete Server ggf. nicht zu sehen)
netstat -tulpe
-
Mit "lsof -in | grep port_number" kann man herausbekommen welcher
Prozess mit dem Port port_number verbunden ist. Als Nutzer kann man
sich nur Prozesse anzeigen, die zu seiner UID gehören. Benutzer
root kann die offenen Verbindungen von allen Nutzern einsehen.
Oder "lsof -i:80": Zeigt alle Verbindungen von/zu Port 80 (http)
Oder "fuser -n tcp ssh": Zeigt die PID des offenen SSH-Ports an.
- "lsof -i UDP -n":
Zeige alle offenen UDP Ports an. Kann nur auf dem Server ausgeführt werden.
Offene Ports auf anderen Rechnern kann man per Portscanning erfahren
(z.B. nmap)
- Broadcast: Wer ist im Netz? (Leider antworten nicht alle
Betriebssysteme)
ping -b 172.168.0.255
- Akustisches Signal, falls Verbindung funktioniert: Während man
unter dem Tisch am Switch oder Hub Netzwerkkabel umsteckt, möchte
man hören wenn die Verbindung funktioniert:
ping -a remote_host
-
Ein Netzwerk mittels einem IP-Filter sicher zu machen ist nicht
schwierig. Da "Verstehen" besser als "SuSE-Firewall" ist,
empfehle ich jedem das kurze Netfilter Howto durchzulesen: Netfilter
Howto
Meine Firewall-Regeln: firewall.sh
Es bringt übrigens keine zusätzliche Sicherheit, wenn man
ungewünschte Pakete mit DROP ignoriert. Ich finde es besser mit
REJECT zu antworten. Das macht das Finden von Fehlern im eigenen
Netz einfacher, da nicht auf ein Timeout gewartet werden muss,
sondern sofort von der Firewall zurückgewiesen wird.
Firewall-Regeln kann man mit iptables-save und -restore
speichern und wieder herstellen. Aus meiner Sicht ist das jedoch
nicht sinnvoll. Meist erstellt man die Firewallregeln in einem
kleinen Shellscript. Die Regeln sind also schon in dem Script
gespeichert. Das lässt sich auch viel besser anpassen als die
Ausgaben von iptables-save. Außerdem kann man im Shellscript
Variablen arbeiten.
- Kommunikation zwischen Client und Server aufzeichnen:
# Verbindung zum Port 80 wird in der Datei capture.dat gespeichert.
# Es werden die ersten 9000 Bytes der Pakete in die Datei geschrieben.
# tcpdump läuft auch auf vielen embedded Systemen wie z.B. OpenWRT
tcpdump -i any -s 0 -w capture.dat port 80
# Nach der Aufzeichnung kann man sich die Datei mit folgendem Befehl
# ansehen:
wireshark -r capture.dat
- Wireshark: Display Filter:
Damit in Whireshark (ehemals Ethereal) uninteressante Pakete ausgeblendet werden,
kann man mit Display Filtern arbeiten:
Display Filter
Kasperfalle:
richtig: !(ip.addr == 1.2.3.4)
falsch: ip.addr != 1.2.3.4 --> Da auf Absender und Empfänger geprüft wird, ist diese Angabe immer richtig!
- Vermeide FTP: Da FTP (File Transfer Protocol) zwei
TCP-Verbindungen benötigt, macht es immer wieder Probleme mit
Firewalls: Bei aktivem FTP baut der Server eine Verbindung zum
Client auf. Der Client hat jedoch meist keine öffentliche
IP-Adresse und ist somit nicht erreichbar. Wegen dem Problem
verwendet man heute meist passives FTP. Bei dieser Variante baut
der Client für den Datentransfer eine Verbindung zum Server
auf. Meist steht der FTP-Server hinter einer Firewall in der DMZ
(Demilitarisierte Zone). Hat das Netz des Server-Anbieters nur eine
öffentliche IP, hat man ein Problem: Einfaches Port-Forwarding
reicht nur für den Steuerkanal, der Datentransfer über die zweite
TCP-Verbindung ist nicht ohne Weiteres möglich, da die Firewall nur
den Port 23 (FTP) weiterleitet.
- Kopieren ohne "Overhead": Dateien kopiert man meist per SSH/SCP
über das Netzwerk. Will man den "Overhead" für die Verschlüsselung
umgehen (oder ist SSH nicht verfügbar), kann man Folgendes
verwenden:
Empfänger (zuerst starten):
netcat -l -p 5555 | tar -xf -
Sender:
tar -cv -exclude=... -f - . | netcat IP-Empfänger 5555
Eine einzelne Datei kann man auch so kopieren:
Empfänger (zuerst starten):
netcat -l -p 5555 | cat > dateiname
Sender:
cat dateiname | netcat IP-Empfänger 5555
In wie weit es eine Beschleunigung gegenüber rsync/scp ist, kommt
auf das Netzwerk und die Hardware der Rechner an. Rsync über einen
SSH-Tunnel benötigt bei einem 1.8GHz Pentium4 10%
CPU-Zeit. Entsprechend wird die Lösung mit netcat kaum schneller
sein. Der Flaschenhals ist nicht das Ver- und Entschlüsseln sonder
das Netzwerk.
- OpenVPN ist eine sehr
einfach einzusetzende VPN (Virtual Privat Network) Software. OpenVPN
wird von Linux, *BSD und Windows unterstützt. Ich kenne keine andere
VPN-Software mit der man eine Verbindung zwischen zwei Rechnern
aufbauen kann, die nur mittels DynDNS erreichbar sind
(also keine feste IP besitzen).
5.7 Latex, Postscript und PDF
[toc]
-
Latex kann WYSIWYG (What you see is what you get) sein: Mittels
Makefile oder Script, aus den Latex-Quellen PS erstellen und im gv
"watch file" anklicken. Nun das Makefile in einer Endlosschleife
jede Sekunden aufrufen und die Anzeige im gv aktualisiert sich,
sobald man die Latex-Datei speichert.
-
Antialiasing by Default in "gv": In /usr/X11R6/lib/X11/app-defaults/GV
oder $HOME/.gv:
"GV.antialias: True"
-
In den meisten Fällen produziert "pdftops" (Teil von xpdf)
besseres Postscript als pdf2ps (Teil von ghostscript). Der
Acrobat-Reader "acroread" hat ebenfalls eine Kommandozeilenoption
um Postscript zu erstellen.
5.8 CD Brennen
[toc]
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.
5.9 Exim / Postfix
[toc]
Als Mailserver verwende ich Exim oder Postfix
- Die wichtigsten Befehle:
| Aktion |
Exim |
Postfix |
Sendmail |
| Print Mailqueue |
exim -bp |
postqueue -p |
sendmail -bp |
| flush queue (send mails now) |
exim -qf |
postqueue -f |
sendmail -q |
| flush queue, retry frozen messages |
exim -qff |
postsuper -H ALL (restart messages from queue 'hold') |
| remove message from queue |
exim -Mrm <message-id> |
postsuper -d <message-id> |
| write mail to stdout |
exim -Mvb <message-id> |
postcat -q <message-id> |
- Die wichtigsten Begriffe bei Exim:
- Transport: Zustellung der Email (SMTP oder lokale Zustellung).
Wird von Director oder Router aufgerufen.
- Router: Für nicht lokale Domains (Ausgehende Emails)
- Director: Für lokale Domains
- Driver: Transport, Router oder Director
Die Reihenfolge in exim.conf ist entscheidend. Falls ein Router oder
Director fehlschlägt (decline) wird der nächste versucht. Falls der
letzte fehlschlägt: failed.
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.
5.11 Zeitserver
[toc]
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.
- Emails im Fehlerfall:
# Siehe "man 5 crontab"
# minute hour day_of_month month day_of_week
00 01 * * * $HOME/bin/myscript >> $HOME/log/myscript.log 2>&1
Nachteil: Die Fehlermeldungen erreichen uns nur per E-Mail, sind
aber nicht im Logfile. Darum Folgendes:
00 01 * * * $HOME/bin/myscript 2>&1 >> $HOME/log/myscript.log | tee -a $HOME/log/myscript.log
Schritt für Schritt, zum Mitdenken:
- Stderr des Scripts wird umgebogen, damit es in die Pipe (| tee
...) schreibt.
- Stdout des Scripts schreibt in das Logfile. Normale Ausgaben
erzeugen keine E-Mail durch Cron.
- Das "tee" liest den ursprünglichen stderr-Strom und gibt ihn auf
stdout aus (Cron nimmt das entgegen und verschickt eine E-Mail) und
hängt ihn außerdem an das Logfile an.
Ziel der Übung: Nur im Fehlerfall eine E-Mail erhalten und die
Fehlermeldung ist außerdem im Logfile.
Hinweis: Unter Unix kann gefahrlos in eine Dateien von
mehreren Prozessen im append-Modus geschrieben werden (Ausnahme:
Dateien, die per NFS eingebunden sind).
- Fehlerfinden bei Cronjobs:
Wenn ein Script funktioniert, wenn es von der Shell aus aufgerufen
wird, heißt noch nicht, dass es klappt, wenn es von Cron gestartet
wird. Grund: Es fehlen Umgebungsvariablen:
- PATH: In der Regel ist der Pfad nur
/usr/bin:/bin. In der interaktiven Shell ist jedoch
meist $HOME/bin und /usr/local/bin auch im Pfad.
- HOST: Diese und andere Umgebungsvariablen sind meist nicht
gesetzt. Hier hilft z.B.
uname -n
Zum Fehlerfinden kann man folgenden Code in eine Datei schreiben, und
sie per Cron aufrufen lassen:
#!/bin/sh
echo `date` >> /tmp/crontest.log
echo env >> /tmp/crontest.log
- Funktioniert ein Script als Cronjob nicht, obwohl es von der
Shell aus aufgerufen funktioniert, kann man wie folgt ausprobieren,
was passiert, wenn keinerlei Umgebungsvariablen übergeben werden:
nutzer@host> env -i myscript # Der Prozess 'myscript' hat keine Umgebungsvariablen
nutzer@host> env -i PATH=/bin/:/usr/bin/ # Der Prozess hat nur die Umgenungsvariable 'PATH'
- Damit die Umgebunsvariablen eines Cronjobs, der interaktiven
Shell entsprechen, lese ich oft die Datei .bashrc vorher ein:
00 01 * * * . .bashrc && bin/myscript.py
5.13 Linux Systemrettung
[toc]
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.
5.14 Debian / Ubuntu
[toc]
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
5.16 Pakete, die man braucht
[toc]
Hier eine Liste von Paketen, die ich normalerweise immer installiere:
pakete.txt
5.17 umount /media/dvd: device is busy
[toc]
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
5.18 SMTP, POP3, HTTP per Telnet
[toc]
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.
5.19 Englisch-Deutsches Wörterbuch
[toc]
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.
5.20 AVI verkleinern
[toc]
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.
- -oac: Output Audio Codec lame. Der mp3 Encoder lame muss installiert sein.
- -ovc: Output Video Codec XVid.
- -srate:
Da mencoder ohne diese Angabe meist folgende Fehlermeldung bringt:
Cannot set LAME options, check bitrate/samplerate,some very low
bitrates (<32) need lower samplerates (i.e. -srate 8000).If
everything else fails, try a preset.
- -o: Beim ersten Durchlauf den Ausgabestrom in den Unix 'Mülleimer' schreiben. Beim zweiten Mal eine Datei erzeugen.
5.21 Anti-Tipps
[toc]
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 |
5.22 Der kleine Unterschied
[toc]
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]
6.1 Python
[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) *~
6.4 Sonstiges
[toc]
7 Web-Design und Web-Entwicklung
[toc]
7.1 Allgemein
[toc]
- Vermeide JavaScript. Als Beispiel: Validierung von
Nutzereingaben. Falls ein HTML-Formular mit JavaScript vor dem
Submit überprüft wird, muss trotzdem auf dem Server nochmal geprüft
werden. Ansonsten können falsche Daten übertragen und gespeichert
werden, falls der Nutzer JavaScript deaktiviert hat, oder er
absichtlich (z.B. per wget oder urllib) ungeprüfte Daten
übermittelt. Wenn also auf der Serverseite geprüft wird, kann man
sich die Prüfung auf der Clientseite sparen.
- Arbeite ohne Frames, denn Bookmarks/Lesezeichen sind bei Frames
nur auf der Startseite möglich.
- Verwende keine Java Applets oder Flash.
- Bilder nicht mit <img width="..." height="..."> verkleinern.
Die Bilder werden bloß kleiner angezeigt, der Browser muss trotzdem
das ganze Bild herunterladen. Außerdem skalieren die meisten
Webbrowser die Bilder schlecht (sie interpolieren nicht), so dass
auch die Bildqualität leidet.
- Gute Seiten sind auch mit Netscape4.7 benutzbar.
- Nicht zu viele Farben. Lieber einen durchgehenden
Farbton. Gutes Farbbeispiel: www.tagesschau.de (Ansonsten
ist die Seite viel zu überladen)
- Gescannte Bilder oder Bilder einer Digitalkamera sollte man als
JPG speichern. Bilder mit großen gleichfarbigen Flächen
(Screenshots, Schriftzug, Computer-Zeichnungen) sollte man als PNG speichern. PNG
komprimiert verlustfrei, während JPEG verlustbehaftet
komprimiert. Folgende Tabelle zeigt einen Screenshot im PNG und im
JPEG Format. Bei der blauen Schrift sind die Artefakte besonders
deutlich.
| PNG 36 kByte |
 |
| JPG 88 kByte |
 |
TIFF sollte man aus meiner Sicht auch vermeiden. Es gibt
viel "Unterformate" von TIFF. Meistens können Anwendungen nur
einen Teil aller möglichen Formate lesen und schreiben.
- Die Syntax von HTML lässt sich leicht mit dem Programm tidy
überprüfen: http://tidy.sourceforge.net/
Um gewisse Warnungen zu ignorieren verwende ich folgendes Script:
my-html-tidy.sh.
- Sehr komfortabel ist das HTML Validator
Plugin für Firefox. Es überprüft jede angezeigte Seite mit Tidy
und Fehler kann man sich im Quelltext farbig anzeigen lassen. Ein
weiteres praktisches Plugin für Webentwickler ist Firebug.
- Links sollten unterstrichen dargestellt werden. Außerdem
sollten nur Links unterstrichen sein. Also: Überschriften, die
nicht anklickbar sind, sollen nicht unterstrichen sein.
- Um zu Testen, ob die eigene Webseite/Webanwendung auch mit dem
Internetexplorer funktioniert, kann man unter Linux ies4linux
verwenden.
- URLs die auf ein Zeil verweisen, dass auf dem gleichen Server
liegt, sollten nicht das Protokoll (
http://..)
enthalten. Erstens: Wird die Seite per https anstatt http
angesprochen, funktionieren die Links nicht mehr. Zweitens lässt
sich die Seite auch per Portforwarding per SSH
(https://localhost:8080 wird zu einem anderen Rechner
weitergeleitet) benutzen. Darum sollte man aus meiner Sicht das base-Tag
nicht verwenden.
- Weiterleiten zu einer anderen Seite:
<head>
<meta http-equiv="refresh" content="5; URL=http://www.teamone.de/selfhtml/">
...
-
Eigentlich ist der Zeichensatz iso-8859-1 der Standardwert bei HTML.
Leider sollte man ihn für einige Browser angeben (Mozilla):
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
...
Es gibt dementsprechend keinen Grund Umlaute als Entities
(ä) zu schreiben.
-
Damit man den HTML-Text auch ein paar Monate später anschauen mag,
sollte man ihn ordentlich formatieren. Ich bevorzuge das Einrücken
mit einem Leerzeichen. Attribute sollten mit Anführungszeichen
eingeschlossen sein:
<html>
<head>
<title>Beispiel</title>
</head>
<body>
<table width="100%">
<tr>
<td>Spalte 1</td>
<td>Spalte 2</td>
</tr>
</table>
</body>
</html>
7.4 JavaScript
[toc]
7.5 Sonstiges
[toc]
8 X-Windows
[toc]
8.1 Einleitung
[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).
- ~/.Xresources:
! ~/.Xresources <guettli@thomas-guettler.de>
! Ich möchte im XTerm nicht nur zwei Seiten zurückblättern können:
XTerm*SaveLines: 1000
! Ghostview: Antialiasing
Ghostview.antialias: True
-
Einen zweiten X-Server starten:
startx -- :1
--> X ist nun auf der achten Konsole (Alt+Strg+F8)
-
Sich in einen anderen Rechner einloggen. Auf dem Rechner
remote_computer muss XDM, GDM oder KDM laufen.
X -query remote_computer
- xdpyinfo: Informationen über den gerade laufenden XServer
-
Als Window-Manager verwende ich am liebsten Enlightenment, da er beim
Drücken von ALT-Tab eine Liste der Fenster untereinander mit Titel
anzeigt. Mittels dem Programm 'xtermset' kann man den Titel von
Terminals ändern, so dass man in der Liste von Enlightenment
übersichtlich zwischen den Fenstern wechseln kann.
- ALT + Linke Maustaste --> Fenster verschieben.
- STRG + Rechte Maustaste im xterm: Schriftgröße ändern.
- Die Namen der vom X-Server bekannten Farben stehen in der Datei /usr/lib/X11/rgb.txt. Mit einem einfachen Script, kann man sich die Farben veranschauchlichen: rgb.txt.html
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.
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.
10.1 SAX vs. DOM
[toc]
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?
- SAX: Diese Methode hat den Vorteil, dass nicht die
gesamte XML-Datei in den Hauptspeicher gelesen werden muss. SAX ist
schneller als DOM. Nachteil: Mit SAX kann keine XML-Datei erstellt
werden.
- DOM: Wenn man wenige Attribute eine XML-Datei lesen,
verändern und wieder zurückschreiben will, ist DOM die bessere
Wahl. Der Vorteil von DOM ist, dass sich die XML-Struktur sehr
leicht wieder in eine Datei schreiben lässt.
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]
- KISS: "Keep it Simple and Stupid". Die geringe Akzeptanz
von großen Standards wie z.B SGML zeigen, dass man versuchen
sollte, die Dinge so einfach wie möglich zu lösen.
- Standards: Standards sind nur sinnvoll wenn die
Kommunikation oder der Datenaustausch standardisiert wird. Bei
vielen Dingen (z.B. Programmiersprachen) ist es sinnvoller *eine*
freie Implementierung zu haben. (Darum kann ich Java und C# nicht
leiden)
- Patente: Mittels Patenten halten sich große Unternehmen
Konkurrenz vom Leib. Leider profitieren hauptsächlich große Konzerne
von Patenten. Für Kleine- und Mittelständische Unternehmen ist die
Anmeldung eines Patents zu aufwendig. Durch Patente geschützte
Monopole hindern den freien Wettbewerb und ermöglichen so
ungerechtfertige Preise. Folgende Dinge kann man als kleiner Mann tun:
- PNG anstatt GIF für Bilddateien verwenden.
- Ogg anstatt MP3
für Audiodateien verwenden, da das Erstellen von MP3s nur mit einer
Lizenz der Frauenhofer-Gesellschaft erlaubt ist!
- xpdf anstatt Acrobat-Reader verwenden.
- Vereine wie FFII unterstützen.
- Du bist nicht allein: Es gibt wohl kein Problem, über das
nicht schon andere gestolpert sind. Wenn man innerhalb von 30 Minuten
keinen Lösung zu einem Problem gefunden hat, sollte man sich an eine
entsprechende Newsgroup oder Mailingliste wenden. Oft reicht es mit
Google in Groups zu suchen.
- Spenden: Open Source Software kostet Geld. Auch wenn die
Software kostenfrei angeboten wird, hat der Entwickler Kosten für
Hardware, Netzzugang und ähnliche Dinge. Eine Spende ist in gewisser
Weise auch eine Art "Dankeschön" zu sagen. Folgende Projekte habe ich
bisher (mit einem kleinen Betrag) finanziell Unterstützt:
2002
2004
2005
2006
2007
- theora.org: Theora is an open video codec being developed by the Xiph.org Foundation as part of their Ogg project
- Adrian Holovaty: Ein
Geschenk aus der Amazon Wishlist, als Dankeschön für Django.
2008
- ie4linux: Internet Explorer für Linux (via Wine)
Regelmäßige Spenden
12 Leseempfehlungen
[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.