Zwischendurch mal was nützliches für alle die — wie ich — viel in Unix-Shells unterwegs sind. Insbesondere für die die — wie ich — auch gerne mal ‚Einzeiler‘ schreiben die über mehrere Bildschirmzeilen gehen… :-)

Das Kommando fc steht für ‚fix command‘, damit wird die zuletzt ausgeführte Zeile zur Bearbeitung im Editor geöffnet. Also idealerweise im Vim. Da kann man komfortabel seine Änderungen vornehmen, direkt nach Beendigung des Editors wird das Kommando ausgeführt. Zumindest die Bash und die Zsh (letztere ist die interaktive Shell meiner Wahl) können das.

Ich persönlich kannte das vorher noch nicht. Hilfreich wäre es schon in wirklich vielen Situationen gewesen: ich neige wie gesagt dazu komplexe Shell-Zeilen zusammenzubauen. Wenn ich mit einem Ergebnis zufrieden bin schiebe ich es oft mittels echo in eine Datei, um die dann zum Shellskript umzuformen. Wenn ich mit fc eh in den Editor wechsele kann ich nicht nur von vornherein sauberer schreiben, sondern bei Bedarf mit ‚:w tollesskript.sh‘ direkt in eine Datei sichern.

Es sind die kleinen Dinge im Leben, die Freude bereiten:

less +F /var/log/syslog

Das funktioniert erstmal ähnlich wie ein tail -f, nur dass nicht die letzten 10 Zeilen der Datei angezeigt werden sondern ‚der letzte Bildschirm voll‘. In der letzten Zeile verrät ein freundliches Waiting for data… (interrupt to abort) was passiert: neuer Inhalt in der Datei wird sofort dargestellt. Der große Vorteil gegenüber tail: nach dem geforderten Interrupt (also CTRL-C) hat man die Datei direkt ganz normal im less offen, kann also beliebig nach Inhalten suchen oder hoch und runter scrollen.

Ich spare mir den Unix is sexy-Gag, obwohl der echt naheliegend ist: Bijo Linux ist eine Art Kommandoreferenz auf Japanisch. Vorgestellt werden allerdings wohl nicht nur die Kommandos, sondern auch die vorstellenden Damen. Ein merkwürdiges Völkchen… :-)
Wer es genauso bedauert wie ich die Sprache nicht zu beherrschen (Japanisch — Shell kann ich halbwegs fliessend!) kann sich übrigens prima bei Google Translate helfen lassen.

Eigentlich fühle ich mich in Unix-Shells halbwegs zu Hause. Trotzdem gibt von Zeit zu Zeit eigentlich einfache Situationen die mich verwirren. Heute war es wieder mal so weit: ein Kollege wunderte sich dass eine Datei von einem Skript nicht kopiert wurde. Quelle sowie Ziel waren les- und beschreibbar, also alles in bester Ordnung. Allerdings gab es eine Fehlermeldung, die aber meiner Meinung die Kopie nicht verhindern sollte.

Um das mal einfach nachzustellen:

$ touch quelle log
$ chmod 444 log
$ cp quelle ziel >> log
zsh: permission denied: log

Natürlich ist das Logfile so nicht beschreibbar. Trotzdem hätte ich damit gerechnet dass die Datei kopiert würde. Wurde sie aber nicht. Weder auf AIX in der ksh, noch in anderen Shells die ich auf anderen Betriebssystemen ausprobiert habe. Hätte ich damit rechnen müssen?

Ich hatte mir mal einen Link gesichert den ich mir ansehen wollte sobald ich wieder auf die Idee käme, mit Daten rechnen zu wollen. Wenn man sich da ansieht was man alles bedenken muss verwirft man schnell alle Ideen die in die Richtung gehen. Das sollen besser andere machen… :-)

Heute war es wieder so weit. OK, kein kompletter Kalender. Aber ich war einsam und alleine in einer Korn-Shell auf Solaris unterwegs und wollte wissen welches Datum wir Gestern hatten. Heute ist einfach, aber Gestern? Mit GNU date sagt man einfach was man will:

date --date yesterday

Unter Solaris ist man von den GNU-Segnungen verschont, da erfordert das einen kleinen Kunstgriff (den ich dann auch im Netz finden konnte):

TZ=GMT+24 date

Man verstellt also einfach (nur für das eine Kommando, nicht für das ganze System!) die Zeitzone um 24 Stunden und fragt dann nach dem Datum. Das funktioniert auch mit mehr als 24 Stunden, und mit negativen Werten für Daten in der Zukunft. Gut zu wissen.

In dem Zusammenhang zitiere ich dann auch nochmal einen Absatz den ich mir vor knapp vier Jahren von blog.detux.de kopiert hatte, es geht um die Unixzeit (auch Unix-Epoche genannt). Den Blog dazu gibt es leider nicht mehr, die Notiz hat sich aber schon mehrfach bewährt:

BASH: Unix-Timestamp in Datum konvertieren
Gerade 10 Minuten nach gesucht, deshalb hier nochmal schnell als Merkzettel:
TIMESTAMP=date +%s DATE=date --date="1970-01-01 $TIMESTAMP sec GMT" echo $DATE
Kann man immer mal wieder gebrauchen…

Etwas konkreter sähe das dann so aus (das Datum ist übrigens der 13. Februar 2009, 23:31:30):

date --date="1970-01-01 1234567890 sec GMT"

Man nutzt hier also den Umstand aus dass Unix die Sekunden seit dem 01.01.1970 zählt und fragt nach wie spät es soundsoviel Sekunden nach eben diesem Datum ist. Logisch. Nicht allzu naheliegend, aber wenn man es weiss: logisch. :-)

Dass man Passworte und ähnlich vertrauliche Sachen nicht in Kommandozeilen verwenden sollte ist mir klar. Jeder der auf dem gleichen System angemeldet ist kann sich mittels ‚ps auxwww‘ den vollständigen Aufruf anzeigen lassen, einschließlich womöglich benutzter Passworte.

Bisher hätte ich in meinem jugendlichen Leichtsinn aber keine Bedenken gehabt, solche Daten in Umgebungsvariablen zu hinterlegen. Klar, irgendwo unter /proc findet man die soweit ich weiß auch wieder. Aber nur wenn man root ist, oder wenn man Spaß daran hat, seine eigenen Prozesse zu bespitzeln. Fremde Prozesse kann man so nicht einsehen.

Es geht aber auch anders: mit ‚ps auxwwwe‘ — das ‚e‘ steht offenbar für ‚Environment‘ — stehen auch Umgebungsvariablen in der Prozessliste. Für alle Benutzer auf dem gleichen System einsehbar, ohne dass die über besondere Rechte verfügen müssen.

Man lernt nie aus… Und nachdem ich das jetzt weiß werde ich erstmal gründlich in mich gehen um rauszufinden wo ich eventuell solche Leichen im Keller habe… :-(

In den letzten Tagen habe ich nach längerer Pause mal wieder ausgiebig mit Nagios gespielt. Bei einer ausgiebigen Umstellung meines Netzes habe ich vor einer Weile den alten Nagios nach /dev/null verschoben, seitdem gab es Blindflug.

Soweit alles prima, allerdings bin ich an einer Stelle hängen geblieben: dem Drucker. Klar kann man einen Laserjet mit Netzwerkkarte problemlos überwachen, problematisch ist nur dass mein Drucker nur alle paar Wochen mal benutzt wird. Dazwischen ist der natürlich ausgeschaltet.

Das Problem: Wenn ich den Drucker ausschalte werden weiter alle Parameter (Tonerstand, Papiervorrat, Nachrichten…) geprüft, was natürlich nur zu Fehlern oder Nonsens führt. Besser fände ich wenn die Parameter den alten Zustand beibehalten würden, und lediglich das Gerät als ausgeschaltet gemeldet wird. Offenbar kann man das so aber nicht konfigurieren. Zumindest habe ich das nicht gefunden, für sachdienliche Hinweise wäre ich dankbar.

Ich habe vorhin mal ein wenig gescriptet, mit diesem Stück Shell geht es dann doch:

#!/bin/sh
host=$1
shift
command=$@
CACHEFILE=/tmp/check_cached.dat
if ping -c 1 $host > /dev/null; then
  # $host is online, fetch fresh data
  output=$(eval $command)
  returncode=$?
  # escape command and remove old entry from cache file
  ecommand=$(echo $command | sed -e "s_/_\/_g")
  sed -i "/^$ecommand;/d" $CACHEFILE
  # append command with fresh values to cache file
  echo "$command;$returncode;$output" >> $CACHEFILE
else
  # $host is offline, fetch data from cache file
  output="cached: $(sed -ne "s#^$command;[0-9];(.*)$#1#p" $CACHEFILE)"
  returncode=$(sed -ne "s#^$command;([0-9]).*$#1#p" $CACHEFILE)
fi
echo "$output"
exit $returncode

Ich habe das unter dem Namen check_cached.sh gespeichert. Jetzt musste ich nur noch das Kommando ändern mit dem der Drucker kontrolliert wird:

define command{
  command_name check_snmp_printer
  command_line /usr/local/nagios/plugins/check_snmp_printer '$HOSTADDRESS$' '$ARG1$' '$ARG2$' '$ARG3$'
}

Daraus mache ich folgendes:

define command{
  command_name check_snmp_printer
  command_line /usr/local/nagios/plugins/check_cached.sh '$HOSTADDRESS$' "/usr/local/nagios/plugins/check_snmp_printer '$HOSTADDRESS$' '$ARG1$' '$ARG2$' '$ARG3$'"
}

Alle Services die check_snmp_printer benutzen sind ab sofort gecached. Rein theoretisch sollte das auch mit allen anderen Checks funktionieren, ich habe das aber selbst mit diesem bis jetzt nur oberflächlich getestet, ich übernehme (natürlich) keine Verantwortung für alles was mit dem Skript oder wegen des Skriptes passiert. :-)

Fragen und Vorschläge fühlen sich hier in den Kommentaren wohl. :-)

Oh, und eine Frage kann ich im Voraus beantworten: Nein, eigentlich brauche ich kein so dickes Netzwerkmanagement in meinem Heim-Netz. Grund für die Bastelei ist Spaß an der Sache, und nachdem ich in letzter Zeit mit einem teuren kommerziellen System arbeiten muss will ich mir zu Hause einfach nochmal klar machen dass man mit der freien Lösung auch das meiste — wenn nicht alles — hinkriegt. :-D

Nachtrag: Momentan stört mich das nicht, aber wer das im großen Stil einsetzen will sollte vielleicht noch was einbauen das dafür sorgt dass auch etwas sinnvolles passiert wenn der Host offline ist, aber noch keine Daten dafür im Cache liegen…

Vorbereitung: apt-get install filters

Dann für einen Überblick:

for i in b1ff chef cockney eleet fudd kenny kraut pirate spammer upside-down; do echo $i; echo "Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun." | $i; echo; done

b1ff
FAR OUT 1N THE UNCHARTED BACKW8RZ UV THE UNFASHIONABLE END UV THE WESTURN SP1RAL ARM UV THE GALAXY LEIZ A SMAL UNREGARDED YELOW SUN.

chef
Fer oooot in zee uncherted beckveters ooff zee unffesheeuneble-a ind ooff zee vestern speerel erm ooff zee Gelexy leees a smell unregerded yelloo soon.
Bork Bork Bork!

cockney
Far out in the bloody uncharted backwaters of the unfashionable end of the flinkin‘ western spiral arm of the Galaxy lies a small unregarded yellow sun.

eleet
f4r 0ut 1n th3 unch4rt3d b4ckw4t3r5 0f th3 unf45h10n4bl3 3nd 0f th3 w35t3rn 5p1r4l 4rm 0f th3 g4l4xy l135 4 5m4ll unr3g4rd3d y3ll0w 5un.

fudd
Faw out in de unchawted backwatews of de unfashionabwe end of de westewn spiwaw awm of de Gawaxy wies a smaww unwegawded yewwow sun, uh-hah-hah-hah.

kenny
Mpfmmmpff ppffmffmp mffppp fmpmfpmpp fmfpppmmfmfpmmmpfffmpmppmpm mmpmmmmmfpmpfppmmmfmpmpppfffmm ppfmpf fmpmfpmpp fmfpppmpfmmmfmmmfpmffppfpppmmmmmppmfmpp mpppppmpm ppfmpf fmpmfpmpp fppmppfmmfmpmpppffppp fmmpfmmffpffmmmpmf mmmpffppm ppfmpf fmpmfpmpp Mfmmmmpmfmmmfpfffm pmfmffmppfmm mmm fmmppmmmmpmfpmf fmfppppffmppmfmmmmpffmpmmppmpm ffmmpppmfpmfppffpp fmmfmfppp.

kraut
Far out in ze uncharted backwaters uff de unfaschionable end uff de vestern spiral arm uff de Galaxy lies a small unregarded yellow sun.

pirate
Far out in th‘ uncharted backwaters o‘ th‘ unfashionable end o‘ th‘ western spiral arm o‘ th‘ Galaxy lies a small unregarded yellow sun, by Blackbeard’s sword.

spammer
Dear Friend, Far
out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded
yellow sun.

This is a one time e-mail!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To be removed from this mailing list send an email and put in the subject the word „remove“.
8D4A20728CC8670635C16C332F1AC2F2A6BF10F91546EECE6641A5F2EAD63C76003F62F2B
6074CB9FC2FDC32EEC1B603FE5BFF77248701E2BE4AB7DA342C4AF5E1E929FB8D08915635103D

upside-down
‚uns mo77ah papje6ajun 77ews e sa!7 hxe7e6 ayf jo wje 7ej!ds ujafsam ayf jo pua a7qeuo!ysejun ayf jo sjafem>|)eq pafjey)un ayf u! fno jej

Den letzten finde ich besonders witzig, auch wenn man da im Vorteil ist wenn man keinen Röhrenmonitor mehr hat: das liest man kopfüber… :-)