readlink -f .
Quelle: Bash equivalent for PHP realpath() | Andy Skelton
Samstag, 11. Dezember 2010
Montag, 6. Dezember 2010
Heute hatte ich es mit einer längst vergessen geglaubten Virtuellen Maschine zu tun, auf welcher noch ein Debian GNU/Linux mit einem 2.4er-Kernel installiert war. Im Grunde ging es nur darum, die aktuellsten VMware-Tools auf dieser Kiste zu installieren — doch wie immer zog dies umgehend einen riesigen Rattenschwanz an Debugging und sonstigen Upgrade-Arbeiten mit sich.
Nach etlichem Pröbeln und apt-get-Endlosschleifen hier die Kurzzusammenfassung, wie man Etch auf Lenny bringt:
Zuerst einmal muss man Etch auf den letzten verfügbaren Stand aktualisieren. Da die Etch-Pakete von den Mirrors verschwunden sind, muss man alle vorhandenen Zeilen in der Datei /etc/apt/sources.list auskommentieren und folgende Zeilen einfügen:
deb http://archive.debian.org/debian-archive/debian/ etch main deb-src http://archive.debian.org/debian-archive/debian/ etch main
Quelle: Debian (etch): sources.list
Natürlich funktioniert das apt-get update auf meiner Installation nicht sauber, weil mir einige PGP-Schlüssel fehlen. Da deren Fingerprint angegeben wird, kann ich diese ganz simpel mit folgendem Befehl mit meinem System bekannt machen:
# gpg --keyserver pgpkeys.mit.edu --recv-key 010908312D230C5F # gpg -a --export 010908312D230C5F | apt-key add -
Quelle: [Debian] Apt-get : NO_PUBKEY / GPG error
Jetzt folgt das obligate
# apt-get update # apt-get install apt aptitude # apt-get upgrade # apt-get dist-upgrade
um die neuesten Pakete zu installieren. Das System ist nun bereit, um auf einen neuen Kernel gehoben zu werden:
# apt-get install linux-image-2.6.18-6-686
Ist der Kernel installiert und GRUB angepasst (geschieht automatisch), sollte man den Server einmal neu starten (reboot).
Frisch zurück im System mit Kernel 2.6, werden die oben hinzugefügten Zeilen nun wieder auskommentiert. Stattdessen fügt man nun folgende Repositories in /etc/apt/sources.list ein:
deb http://mirror.switch.ch/ftp/mirror/debian lenny main deb-src http://mirror.switch.ch/ftp/mirror/debian lenny main deb http://security.debian.org/ lenny/updates main
Quelle: Upgrading Debian Etch to Lenny stuck on kernel/libc issue
ACHTUNG: Anstelle dieses kritische Kernel-Upgrade nun mit apt-get zu machen, hält man sich lieber an die Anweisungen der Debian-Maintainer und verwendet aptitude. Dieses kann viel besser mit Abhängigkeiten umgehen (Stichwort: libc6, dpkg (mit Breaks) etc.)
# aptitude update # aptitude upgrade # aptitude dist-upgrade
Quelle: Howto Upgrade Debian 4 Etch to Debian 5.0 Lenny
Dies bringt alle Pakete auf den neuesten Stand, die für das nun definitive dist-upgrade zwingend sind.
Da die Kernel-Sourcen für Kernel 2.6.18 irgendwie nicht verfügbar sind, aktualisiert man kurzerhand auf Kernel 2.6.26:
# apt-get install linux-image-2.6.26-686 # reboot
Damit die VMware-Tools korrekt installiert werden können, lädt man sich nun auch noch die korrespondieren Quellen herunter:
# apt-get install linux-headers-`uname -r`
Anschliessend spielt man die VMware-Tools in gewohnter Manier ein. Fertig!
Dienstag, 30. November 2010
Heute konnte ich auf der Arbeit wieder einmal einen ausgemusterten PC mit Debian GNU/Linux versehen und zu einem Server (cups mit Samba inkl. Windows-Druckertreiber) umwandeln. Obwohl heuer, 2010, die Installation eines Linux-Betriebssystems kaum mehr grosse Mühe bereitet, fanden sich auch dieses Mal wieder Stolpersteine.
Konkret: Die Installation hing beim Aktualisieren der Pakete über den Internet-Mirror von SWITCH. Der Fortschrittsbalken im Dialog „Select and Install Software“ blieb bei 1% stecken und bewegte sich auch nach mehreren Minuten warten nicht weiter.
Nach etwas Googeln fand ich als erstes heraus, dass man mit Druck auf die Tasten Ctrl-Alt-F4 in die textbasierte Log-Ansicht der Installationsroutine schalten konnte. Dort stand etwas in der Form:
... Nov 30 15:04:00 in-target: To continue, enter "Yes"; to abort, enter "No"
Die Installation hing also, weil die Entwickler der Routine nicht vorhergesehen hatten, solche Eingabeaufforderungen automatisch mit „yes“ zu beantworten.
Als nächstes startete ich deshalb den Rechner neu, spielte die Installation durch, vermied es aber tunlichst, die Netzwerkkarte zu konfigurieren. So wurde die Internet-Aktualisierung zwar übersprungen und der Rechner bootete nach der Installation brav in die Shell — doch ich war danach aber schlichtweg nicht in der Lage, das Netzwerk zu laden (wahrscheinlich hätte ich das entsprechende Treibermodul laden müssen). Es trennt mich somit noch ein weiter Weg bis zum bombensicheren Linux-Admin.
Also hiess es ein weiteres Mal zurück zum Start. Dieses Mal initialisierte ich die Netzwerkkarte wieder von Beginn weg mit den benötigten Informationen. Als der Balken aber erneut hing, wechselte ich mittels Ctrl-Alt-F2 in ein interaktives Shell. Dort versuchte ich mich der brachialen Methode:
# ps ax | grep aptitude 5760 ? Ss 0:00 aptitude ... # kill 5760
Der blockierte Prozess wurde so nullkommaplötzlich abgetötet. Mittels Ctrl-Alt-F1 ging es zurück in den Installationsbildschirm, wo mir eine rotgefärbte Fehlermeldung entgegenleuchtete und mir mitteilte, dass der wichtige Prozess verschwunden war.
Ich folgte den Anweisungen auf dem Bildschirm, drückte „Continue“, um die Installation trotz des Fehlers fortzusetzen und wählte aus der nun angebotenen Liste aus, dass nun der Bootloader grub in den MBR der Festplatte geschrieben werden sollte.
Die Installation lief durch, der Rechner startete neu — und sobald ich mich eingeloggt hatte, führte ich folgenden Befehl aus:
# apt-get update ... # apt-get dist-upgrade
So hievte ich mein Debian GNU/Linux 5.0.6 auf 5.0.7 — und der Tag war gerettet.
Tags: Debian, IT-Support
Labels: Linux
Dienstag, 26. Oktober 2010
How do you hire a programmer if you’re not one yourself? Some things to look for …
1. How opinionated are they?
Ask them about a juicy programming topic (e.g. Ruby or Python?). The tone and reasoning of the answer will reveal a lot. In our recent podcast on programming, Jeff said, “When people have strong opinions about things — when they can talk at length about something — it’s a good indication that they’re passionate about it.”
Quelle: How to hire a programmer when you’re not a programmer – (37signals)
Genau dies habe ich letzte Woche erlebt. Ich auf der Seite des Programmierers, auf der anderen Seite ein Headhunter, der für ein „internationales“ Unternehmen in Zürich einen Web-Entwickler suchte. Er war über Xing an meine Kontaktangaben gelangt.
Auf die Frage, ob ich Erfahrung in ASP.NET hätte, erwiderte ich ein klares Nein, um anzufügen, dass ich das letzte Mal im Jahr 2000 ASP programmiert hätte. ASP war damals mein erster Einstieg in webbasierte Scriptingsprachen. Innert weniger Monate wurde ich dann aber äusserst rasch auf die gute Seite der Macht gezogen — und entwickelte fortan auf den LAMP-Stack aufbauend.
Der Headhunter hakte nach: Ob ich es mir denn vorstellen könne, ASP.NET zu erlernen? Darauf erwirderte ich ein klares und dezidiertes „Nein“. Ich, der Mac OS X/Linux-Fan, der plötzlich in Visual Studio rumeiert? Das wäre wie wenn ein Kommunist zur SD überlaufen würde. Oder ein Wechselstromverfechter ins Camp der Gleichstromfreaks übertreten würde.
Ich habe mich noch ein/zwei Male gefragt, ob ich wirklich die richtige Antwort gegeben habe — doch mit obiger Bemerkung von Seiten der Web-Entwicklerprofis bin ich ein für allemal sicher, dass ich mich richtig entschieden habe.
Tags: Apache, ASP, LAMP, Microsoft, MySQL, Opensource, OSS, PHP
Labels: IT, Linux, Web
Samstag, 14. August 2010
Seit vielen Jahren verwende ich das IMAP-Protokoll zum Zugriff auf alle meine Mail-Adressen. Doch leider nimmt die Mailflut immer mehr zu, und das stört.
Bis zum heutigen Tag habe ich mich „Regeln“ in Apple Mail beholfen, um Mails beim Eintreffen in die entsprechenden Unterordner abzulegen. Seit ich aber einen Laptop und ein iPhone besitze und zunehmend auch unterwegs Mails abrufe, wäre es äusserst nützlich, wenn ich eingehende Mails vollständig automatisch serverseitig vorsortieren und in Unterordner ablegen könnte.
Bisher war ich dazu genötigt, die Regeln von Apple Mail auf meiner Workstation zu Hause auf den Laptop zu übertragen. Immer wieder habe ich mir dabei vorgenommen, diese Redundanz aufzuheben. Heute ist es nun soweit!
Was tun? Wer einen dedizierten Mailserver im Keller stehen hat, wird sich auf procmail-Scripts stützen (ich habe auch schon darüber berichtet), die eingehende E-Mails nach bestimmten Kriterien in Unterordner verschieben. Dies ist für mich keine Option, weil mein von Genotec betriebener Mailserver keinen Shellzugriff bietet. Auch bietet der Hoster keine anständige Möglichkeit an, serverbasierte Filter einzurichten.
Heute nun bin ich via einer diesbezüglichen Frage auf der Community Serverfault auf imapfilter gestossen.
Zuerst installiert man sich das Paket unter Debian auf einem ans Internet angeschlossenen Server, der nonstopp läuft:
apt-get install imapfilter
Anschliessend schreibt man sich mit der Sprache Lua (vgl. die Beispiele Rotating email into your inbox using imapfilter sowie sample.config.lua.txt) entsprechende Filter-Rezepte und legt diese nach einem chmod 600 * im Homefolder beispielsweise unter ~/.imapfilter/filter/ ab.
Nachfolgend ein solches „Rezept“ für einen meiner Mailkonti:
mbox = IMAP {
server = 'mail.server.tld',
username = 'user@domain.com',
password = '********',
ssl = 'ssl3'
}
-- Facebook
messages = mbox.INBOX:contain_from('facebookmail.com')
messages:move_messages(mbox['Facebook'])
...
-- AHC
messages = mbox.INBOX:contain_field('List-ID','gi-ch.googlegroups.com')
messages:move_messages(mbox['AHC'])
...
Wie man anhand dieses Beispiel sieht, kann man jedes beliebige Feld des Mail-Headers auswerten. Als Hilfe für alle verfügbaren contain_X-Befehle sei auf die Dokumentation unter imapfilter_config – imapfilter configuration file verwiesen. Es gibt auch noch andere Befehle, die es ermöglichen, noch deutlich feingranuliertere Regeln zu programmieren.
Hat man wie ich mehrere Mail-Konti, die abgegrast werden sollen, erstellt man entsprechende Filter für jedes Konto und legt diese im selben Ordner unter einem aussagekräftigen Namen ab.
Damit man diese nun alle auf’s Mal durchackern lassen kann, empfiehlt sich, ein kleines Shell-Script zu schreiben:
#!/bin/sh
IMAPFILTER=`which imapfilter`
RECIPESROOT="~/.imapfilter/filter"
cd $RECIPESROOT
for RECIPE in *
do
#echo "Running $IMAPFILTER -c '$RECIPESROOT/$RECIPE'"
$IMAPFILTER -c "$RECIPESROOT/$RECIPE"
done
exit 0
Anschliessend richtet man einen Cron-Job ein, der die Mailserver beispielsweise alle 5 Minuten nach neuen Nachrichten abfragt und je nachdem die Filterregeln anwendet:
*/5 * * * * /usr/local/bin/imapfilter.sh
Fertig ist der kostenlose, transparente Filterservice für eingehende Mails.
Mittwoch, 28. Juli 2010
Seit einigen Wochen offeriert mir Debian bei jedem apt-get dist-upgrade, mein System auf ein abhängigkeitsbasiertes Bootsystem („dependency-based boot system“) umzustellen.
Leider ist dies bisher jedesmal gescheitert, weil folgende init.d-Skripte die Umstellung verhindert haben:
'libdevmapper1.02' missing LSB tags and overrides, 'iptables' missing LSB tags and overrides, 'xfree86-common' missing LSB tags and overrides, 's3sqld.init' missing LSB tags and overrides, 'libdevmapper1.00' missing LSB tags and overrides, 'dhcp' missing LSB tags and overrides, 'raid2' missing LSB tags and overrides, 'rendezvous' missing LSB tags and overrides,
Gestern habe ich mir nun endlich die Mühe genommen, mein System zu durchforsten, aufzuräumen und auf die neue Boot-Methode umzustellen. Wie es sich herausstellte, war es doch nicht so kompliziert, wie ich es befürchtet hatte.
Zuallererst ist zu überprüfen, ob das bemängelte Script tatsächlich noch vom System benötigt wird oder ob es bei einem apt-get remove <package> versehentlich zurückgelassen wurde.
Als erstes sucht man deshalb auf packages.debian.org mit der Suchfunktion unter „Search the contents of packages“ nach der entsprechenden Datei. Kann diese in keinem aktuellen Paket gefunden werden, ist es wahrscheinlich, dass es sich um ein Überbleibsel handelt. Zur Sicherheit kann man mittels dpkg --list | grep <vermutetes package> überprüfen, ob das Paket tatsächlich vor langer Zeit entfernt wurde (rc steht in diesem Fall zu Beginn der Zeile).
Wird die Datei hingegen irgendwo gefunden, muss man mittels Google herausfinden, ob und wie das init-Skript von Hand angepasst werden kann, um die geforderten „LSB tags“ und „overrides“ eingepflegt zu erhalten.
Konkret sah das Prozedere bei mir folgendermassen aus (Achtung: Sicherheitskopien sind ratsam, um notfalls nicht das gesamte System zu zerschiessen):
Schlussendlich kann man die Boot-Methode nun umstellen:
# dpkg-reconfigure sysv-rc info: Checking if it is safe to convert to dependency based boot. info: Reordering boot system, log to /var/lib/insserv/run-20100727T1330.log success: Enabled dependency based boot system.
Montag, 5. April 2010
… ist es an der Zeit, in der Datei /etc/hosts.allow endlich folgenden Eintrag anzufügen:
... sshd: 192.168.0.2 ...
Wobei hier natürlich anstelle von 192.168.0.2 die IP-Adresse angegeben werden sollte, die der Client (also die Workstation, von welcher man sich per SSH auf den Server verbindet) trägt.
Via: Debian Linux Stop SSH User Hacking / Cracking Attacks with DenyHosts Software
Tags: Sicherheit
Labels: Linux
Sonntag, 13. Dezember 2009
Gestern um 20:00 begann ich damit, meinen Heimserver dem grössten Upgrade in seiner Geschichte zu unterziehen. Zwei Gründe bewegten mich zu diesem Entscheid: Einerseits war das Gerät längst betagt und mittlerweile äusserst schwach auf der Brust. Andererseits kämpfe ich seit dem Sommer 2009 sporadisch mit „Black Screens Of Death“, welche nur mit einem Reset zu beheben waren. Natürlich machen solche Ausfälle bei einem eigentlich 24/7 verfügbaren Server keinen Sinn. Leider brachte die Fehlersuche über Monate hinweg keine Ursache zu Tage. Vermutlich lag es an der Altersschwäche eines Bauteils.
Was hat sich in der Hardware geändert?
... DEVICE partitions ... ARRAY /dev/md10 metadata=0.90 UUID=8b74168f:921d62ec:197e72a9:dcc396dd ARRAY /dev/md11 metadata=0.90 UUID=c7acb783:7d200806:ba3b0bb9:fba14ed1 ARRAY /dev/md1 metadata=0.90 UUID=0b0b49d4:63eada39:e2d889b1:01493278
Die UUIDs waren glücklicherweise in der alten mdadm.conf hinterlegt. Sie sind unbedingt zu notieren und an einem sicheren Ort aufzubewahren. Anschliessend klappte es problemlos, die RAID-Arrays mittels # mdadm --assemble /dev/md0 etc. zu starten (natürlich in der richtigen Reihenfolge, d.h. /dev/md1 am Schluss, wenn die RAIDs der beiden USB-Platten gestartet wurden. Ob metadata=0.90 wirklich nötig ist, weiss ich nicht. Als ein Array nur im auto-read-only-Modus gestartet wurde, führte ich folgenden Befehl aus, um auch Schreibvorgänge zu ermöglichen (im Grund ja unnötig, da wir nur Daten ab der Platte kopieren wollen):
# mdadm --readwrite /dev/md10
sent 460359385722 bytes received 762070 bytes 38412962.39 bytes/sec total size is 460300401834 speedup is 1.00
— 38 MB/Sekunde sind kein schlechter Wert für ATA-7 über USB auf SATA.
# lsusb ... Bus 002 Device 002: ID 03f0:1017 Hewlett-Packard LaserJet 1300 ...
Dieser Befehl findet sich im Paket usbutils
Sonntag, 13. September 2009
Gerade würgt sich mein HP Laserjet 1300 – immerhin ein Postscript-Drucker mit einem RAM-Upgrade – durch einen Druckauftrag, den ich aus Adobe Acrobat 9 ausgelöst habe. Da für den Druck einer Seite etwa 10 Minuten vergehen (!), wurde mir die Sache zu blöd und ich suchte nach Möglichkeiten, den Druckauftrag zu löschen.
Da er unter Mac OS X bereits an den Druckerserver raus ist, muss ich Linux und lprng bemühen. Wie es sich herausgestellt hat, ist die Verwaltung von Druckjobs äusserst simpel – wenn man denn weiss, wie:
# lpq -Plaserdrucker Printer: Laserdrucker@ALPHA 'HP Laserjet 1300' Queue: 2 printable jobs Server: pid 26486 active Unspooler: pid 26487 active Status: waiting for subserver to exit at 00:51:43.257 Rank Owner/ID Pr/Class Job Files Size Time stalled(672sec) mario@beta+327 A 327 657247.pdf 19804211 00:41:08 2 mario@beta+514 A 514 657247.pdf 8249902 00:47:05 done mario@beta+970 A 970 studium:glossar-fra 326256 16:17:30
19804211 Bytes? 19 MB sind viel, kommen aber offensichtlich hin, denn ich drucke einen 18-seitigen Scan eines Artikels, den ich auf JSTOR gefunden habe.
Um einen Druckauftrag in der Warteschlange zu löschen, muss man sich die Zahl unter Job merken und gibt anschliessend auf der Kommandozeile folgendes ein:
lprm -Plaserdrucker 327 Printer Laserdrucker@ALPHA: checking perms 'mario@beta+327' dequeued 'mario@beta+327'
Quelle: In Unix, how do I print files and list or remove print jobs?
Freitag, 4. September 2009
Gestern habe ich bei Lonely Planet drei PDFs über Togo, Burkina Faso und Ghana bestellt. Obwohl ich West Africa bereits als Hardcopy im Regal stehen habe, sind diese ziegelsteingrossen und -schweren Reiseführer nunmal einfach nicht bequem, um sie mit auf Backpacking-Reisen zu nehmen.
Zwei Lösungen gibt es für das Problem: Eine Bekannte, die ich im Februar in Indien kennengelernt habe, reisst sich die Seiten vor ihren Reisen kapitelweise aus dem Reiseführer. So geht sie sicher, dass sie nur das nötigste mit dabei hat und dies äusserst handlich irgendwo verstauen kann. Mir aber widerstrebt es, Reiseführer einfach so zu „zerreissen“, weshalb ich die zweite, deutlich fortschrittlichere Lösung bevorzuge: Pick&Mix – Lonely Planet-Kapitel in Form von PDFs. Kein Passwortschutz, keine Restriktionen bezüglich Druck. Und zudem spottbillig (das grösste Kapitel – Ghana – hat mich 2.47 EUR gekostet).
Lonely Planet hat erkannt, dass man es den potentiellen Kunden äusserst einfach machen muss, damit sie das neue digitale Produkt in Scharen kaufen – kein DRM und auch keine Paranoia, dass die Kapitel alsbald auf Tauschbörsen auftauchen (obwohl, ein Wasserzeichen könnte ja wohl kaum Schaden). Während die Musikindustrie Jahre benötigte, um sich zu Downloads im weltweit anerkannten MP3-Standard durchzuringen, scheint der Prozess bei Lonely Planet deutlich simpler abgelaufen zu sein.
Item. Heute bekam ich nun ein kurliges Mail von einem Shop Batch User <support@lonelyplanet.com.au>, welches wiederum ein Mail enthielt. Doch im Grossen und Ganzen sah das Layout nicht wirklich überzeugend aus – da musste etwas schief gelaufen sein!
Ein Blick in den Quelltext des E-Mails (unter Apples Mail.app mittels Apfel+Alt+U) zeigte zweierlei:
JVBERi0xLjMNCiXi48/TDQoyIDAgb2JqDQo8PA0KL1R5cGUgL0ZvbnREZXNjcmlwdG9yDQovQXNj ZW50IDcyMA0KL0NhcEhlaWdodCA2NjANCi9EZXNjZW50IC0yNzANCi9GbGFncyAzMg0KL0ZvbnRC Qm94IFstMTc3IC0yNjkgMTEyMyA4NjZdDQovRm9udE5hbWUgL0hlbHZldGljYS1Cb2xkDQovSXRh bGljQW5nbGUgMA0KL1N0ZW1WIDEwNQ0KPj4NCmVuZG9iag0KMyAwIG9iag0KL1dpbkFuc2lFbmNv ...
Glücklicherweise war es mit dem Hinweis auf Content-Transfer-Encoding: base64 äusserst simpel, das encodierte Attachment wieder in eine richtige Datei umzuwandeln. Zuerst kopierte ich den ganzen Textwust in eine Textdatei und speicherte diese als lonely.b64 ab.
Anschliessend machte ich mich auf die Suche nach einem Kommandozeilentool, welches Base64-enkodierte Dateien dekodieren konnte. Dank Google wurde ich mit Base64 umgehend fündig.
Dank MacPorts war das Teil schnell heruntergeladen und kompiliert:
# port install base64
Nun war ich nicht mehr weit von der dekodierten Datei entfernt:
$ base64 -d lonely.b64 lonely.unk
Ein Blick in den Header der Datei zeigte mir klar an, um was für ein Ursprungsformat es sich beim Attachment handelte:
%PDF-1.3 %???? 2 0 obj << /Type /FontDescriptor /Ascent 720 /CapHeight 660 /Descent -270 /Flags 32 /FontBBox [-177 -269 1123 866] /FontName /Helvetica-Bold /ItalicAngle 0 /StemV 105 >> endobj 3 0 obj ...
PDF! Deshalb passte ich die Dateiendung an, und scho sah ich die Tax Invoice von Lonely Planet in Apples Preview.