Automatischer Jabberstatus mit zsh und screen
Reverse-Tabbing für Nicht-Fische
An sich mag ich das Konzept von fish ja nicht besonders – Ich glaube nicht an "Die eine Konfiguration mit der alle zufrieden sind", ausserdem ist 'ne nicht konfigurierbare Shell doch langweilig ;-) – aber die Shell hat doch einige sehr nette Features.
Eines davon ist der in der Shell angezeigte Verzeichnisname:
derf@saviour ~> cd lib/pics/wallpapers/
derf@saviour ~/l/p/wallpapers>
Wie man sieht, wird der gesamte Pfad angezeigt, von allen übergeordneten Verzeichnissen jedoch nur der erste Buchstabe (ich bezeichne das meist als "reverse tabbing").
Da ich aber nicht wegen eines einzigen Features die zsh aufgeben wollte, präsentiere ich hier: reverse-tabbing für die zsh!
Das ganze ist eine kleine Shell-Funktion, welche einfach den gesamten Pfad durchgeht und daraus einen fish-ähnlichen Pfad erzeugt, der auf Wunsch sogar so gewählt werden kann, dass er bei einem normalen Tabben (fast) immer wieder zum tatsächlichen Pfad wird.
Diese Funktion wird entweder mit setopt prompt_subst
als $(rtab)
in den
Prompt geschrieben, oder als psvar[n]=$(rtab)
in der Funktion chpwd
, wobei
der Prompt %nv
enthalten würde.
Usage: rtab [-f -l -s -t] [directory]
-f, --fish fish-simulation, like -l -s -t
-l, --last Print the last directorys full name
-s, --short Truncate directory names to the first character
-t, --tilde Print ~ for the home directory
Ich persönlich bevorzuge rtab -f, welches in meiner Shell dann schon sehr fish-ähnlich aussieht.
derf@saviour ~ > cd lib/pics/wallpapers
derf@saviour ~/l/p/wallpapers >
Gesammelte Logfiles per IRC
{
sleep 5
echo ':j #xtail'
echo ':s #xtail'
sleep 2
sudo xtail /var/log/daemon.log /var/log/faillog \
/var/log/kern.log /var/log/lighttpd/access.log \
/var/log/lighttpd/error.log /var/log/vsftpd.log /var/log/mpd
} \
| sic -h $lokaler_ircd -n $host > /dev/null &
So lassen sich die Logs mehrerer Maschinen ueberwachen, ohne staendig zwischen Terminals zu wechseln. Mal schauen, was daraus noch wird.
Paketsystem #2
Das Paketgedoens besteht im wesentlichen aus 3 Skripten:
- bootstrap wird z.B. per scp auf einen Host kopiert und erstellt dort ein paar Verzeichnisse (~/bin, ~/packages...) und installiert das "core"-Paket mit pkg und checklinks manuell.
- checklinks liest die Datei .links im aktuellen Verzeichnis aus und erstellt daraus symlinks (hardlinks sind auch moeglich)
- pkg installiert, aktualisiert und entfernt die Pakete und ruft z.B. checklinks auf
Ein Paket ist dabei folgendermassen aufgebaut:
.links | Linkbeschreibungen fuer checklinks, z.B. "soft .zshrc packages/zsh/etc/rc" (relativ zu $HOME) |
---|---|
conflicts | Konflikte mit anderen Paketen |
dependencies | Abhaengigkeiten auf andere Pakete |
description | Paketbeschreibung fuer pkg info |
priority | Integer-prioritaet des Pakets |
bin/ | Executables fuer ~/bin. |
etc/ | Konfigurationsdateien |
hooks/ | Shell-Snippets, die nach/vor dem installieren/updaten/entfernen eines Pakets ausgefuehrt werden |
lib/ | Sonstiges, z.B. Bilder |
man/ | Manpages im pod-format |
Die Inhalte von bin/ und man/ werden automatisch von den entsprechenden Orten gesymlinkt und die Symlinks beim deinstallieren des Pakets auch wieder entfernt. Enthaelt bin/ Perlskripte mit pod, werden daraus ebenfalls automatisch manpages generiert. Der Wert aus priority wird beim Deinstallieren beruecksichtigt.
Als DVCS werden sowohl hg als auch git unterstuetzt.
Probleme dabei:
- Es gibt keine Paketliste, weder auf dem Server noch lokal. D.h. Auf Updates
wird bei mercurial via
hg incoming
und bei git gar nicht geprueft, ausserdem muss bei der Installation das DVCS separat angegeben werden. Die Updates sind dementsprechend sehr langsam. - Dadurch bedingt: Das Dependency- und Conflicts-System ist nicht 100%ig verlaesslich, Reverse-Dependencies z.B. fuer Paketdeinstallation gibt es nicht.
- Das gesymlinke funktioniert mittlerweile recht gut, es gibt aber immer noch Faelle in denen tote Links entstehen koennen (z.B. wenn bei einem Paketupdate ein Eintrag aus .links verschwindet)
- Es muessen mehrere Versionskontrollsysteme unterstuetzt werden, das Frontend (pkg) muss also entweder den kleinsten gemeinsamen Nenner bieten oder ein System (in diesem Fall git) wird nicht vollstaendig unterstuetzt.
Alles in allem funktioniert es aber erstaunlich gut, und entgegen anderer Vorhersagen hatte ich damit bisher auch noch keinen Datenverlust ;-)
Das Fazit also: Nimmt man ein (D)VCS als basis ist ein minimales Paketsystem nur sehr wenig Arbeit und leicht zu schreiben. Bis zu einem gewissen Grad kann man sich an der Verzeichnisstruktur als "Paketliste" orientieren und braucht ausser ein wenig Shell und einem symlink-Skript keine weiteren Hilfsmittel. Soll es aber komplexer werden (z.B. Reverse-Dependencies oder verschiedene Repo-Formate) wird man um Komplexe Loesungen wie eine Paketliste nicht herumkommen.
Nochmal was zum Paketsystem
...diesmal aber auf Deutsch
Erstmal was zur Geschichte, also dazu, wie es ueberhaupt soweit kam:
Am Anfang war das $HOME.
Und das $HOME war das einzige weit und breit, weshalb es keine zu
synchronisierenden Dateiversionen gab.
Mit der Zeit kamen allerdings weitere Accounts dazu, und die Bequemlichkeit
verbot es, staendig Konfigurationsdateien per scp hin- und herzuschieben.
Also entstand /home 1.0: Configs wurden nach ~/etc gesymlinkt, ~/etc und ~/bin
wurden mit einem DVCS getrackt und regelmaessig auf die verschiedenen Accounts
verteilt.
So lief es einige Monate lang gut. Die Dateien wurden bevorzugt auf $server
editiert und andernfalls schnellstmoeglich dorthin gepusht, die Merges hielten
sich in Grenzen, und ich konnte ueberall dieselben Dotfiles nutzen.
Mit der Zeit fielen dann aber einige Nachteile auf:
- Groessere Dateien lassen sich nur schlecht im Repo speichern, es sei denn, man will auf jeder Maschine (unabhaengig davon, ob man die Dateien braucht oder nicht) ein grosses Repository auschecken
- Man kann entweder keine sensiblen Daten tracken oder die Repos nur auf "vertrauenswuerdigen" Maschinen benutzen
- Das ganze System ist unflexibel. X-Skripte oder -Configs auf nem schnoeden Shellaccount bringen es nicht
Also wurden die beiden Repositories weiter aufgeteilt. Und da ich keine Lust
hatte, dutzende male hg clone $repo
/ hg update
einzugeben oder auf jedem
Host eigene Skripte dafuer zu haben, gab es dazu direkt noch ein minimales
Paketsystem inklusive Bootstrap-Skript. /home 2.0 war geboren und funktioniert
jetzt seit knapp 2 Monaten.
Ein eigenes Paketsystem ist uebrigens erstaunlich einfach zu schreiben, jedenfalls wenn man es auf einem DVCS basiert. Alles was man braucht ist ein kleines Skript, welches die Repos auscheckt und auf Befehl aktualisiert/entfernt, und ein Skript, welches via symlinks dafuer sorgt, dass die Paketinhalte auch z.B. unter ~/.zshrc benutzt werden koennen. Inzwischen ist es natuerlich gewachsen, so werden z.B. aus Perlskripten mit pod automatisch manpages erstellt und ~/bin automatisch (ohne manuelles Eintragen der symlinks in einer Datei) "bevoelkert", aber das Grundprinzip ist immer noch sehr simpel.
Nebenbei kann man so natuerlich einiges ueber Paketsysteme lernen und seine Shell-skriptingkenntnisse aktuell halten, fuer den gelangweilten Nerd also durchaus empfehlenswert.
Und da ich jetzt muede bin, noch ein paar Statistiken. Genauere Infos, wie und was alles funktioniert (und was nicht) folgen demnaechst™.
- Anzahl aller Pakete: 50
- Anzahl der Revisionen im "core"-Paket (Paketverwaltung, bootstrap, Symlinker): 204
- Groesstes Paket: 68MB
- Gesamtgroesse aller ausgecheckten Pakete: 421MB
"Zwischenrufe" in irssi
Problem: Man schreibt an einer langen Nachricht und moechte zwischendurch einen kurzen Kommentar abgeben.
Loesung: Eingabezeile mit ^U (erase_line) loeschen, Kommentar schreiben und abschicken, mit ^Y (yank_from_cutbuffer) die alte Eingabezeile wiederholen und weiterschreiben.
Alternativ: Eingabezeile mit ↓ leeren, was schreiben und die alte Eingabe mit ↑ ↑ wiederholen
Drogen
Jun 19 16:33:33 kraftwerk sshd[4937]: Invalid user deutch from 89.96.55.15
Jun 19 16:33:34 kraftwerk sshd[4941]: Invalid user german from 89.96.55.15
Jun 19 16:33:35 kraftwerk sshd[4944]: Invalid user hitler from 89.96.55.15
Manchmal fragt man sich ja schon, was diese Leute so rauchen...
An own package system
As you might or might not know, I've been tracking my ~/bin and ~/etc with mercurial for quite some time now.
The advantage of this is clear: One's able to revert changes, has a version history, and especially it's really easy to keep the homes on several machines in sync. However, after some months of usage, I discovered some flaws in this system:
- There's no separation between 'public' and 'private' content, which means you either have to trust the machine's owner or you aren't able to use your repository
- Also, because of this you have to use separate repositories if you want to make your ~/bin and ~/etc public
The first idea was to create repositories within ~/bin and ~/etc separating the public from the private stuff. Instead, I borrowed some ideas from GoboLinux and created repositories sorted by topic, like, 'X' or 'zsh'. This is my setup:
- Every machine has ~/packages and ~/bin
- There's a 'root' machine containing all available packages
- When setting up a new machine, a script is used to retrieve the core package, containing the pkg script for installing additional packages
- Packages usually contain the directories bin/, etc/ and hooks/ and the files .links and .deps
- etc/ contains configuration files, hooks/ contains commands to be executed after installing/removing/updating a package
- bin/ contains executables which are symlinked from ~/bin using the checklinks script, which reads the links from .links
- .deps contains other packages the current one depends upon
I've been using this setup for some days now and it's working quite well so far.
Raumtemperaturverlauf ohne Thermometer
... So geht es natuerlich auch ;-)
Lyrics auf Knopfdruck [aka: Linux ist toll]
Man nehme:
- Musik
- Ein Skript, um das aktuell laufende Lied abzufragen
- Ein Skript, um zu einem Lied lyrics zu kriegen
Und klebe das alles mit ein wenig Shell zusammen:
ARTIST=$(np artist); SONG=$(np song); lyrics "$ARTIST" "$SONG" | \
zenity --width=500 --height=600 --text-info --title="$ARTIST - $SONG lyrics"
Dann noch das ganze in $windowmanager auf ne Tastenkombination legen und sich nen Keks freuen!
zsh magic
incoming/4; eval *
Tut dank autocd und suffix aliases dasselbe wie feh -Tfull incoming/4/\*
Selbst ohne die ganzen restlichen Features, alleine fuer sowas lohnt sich
diese Shell schon ;D