Alle Beiträge von adlerweb
Linux: Single-Thread-Programme auf Multicore-Rechnern parallelisieren
*Auf Uhr tipp* Dauert mal wieder lange, das berechnen – kein Wunder, denn die Software, welche ich hier einsetze, kann nur einen einzigen CPU-Kern nutzen. Wäre doch schön, wenn man so Aufgaben beschleunigen kann, oder?
In meinem Fall heißt die „Bremse“ Tesseract, ein open source OCR-System um eingescannte Dokumente in Text zu verwandeln. Bisher fütterte ich jede Seite nacheinander an das Programm um im Anschluss eine zusammengesetzte PDF zu generieren. Eine einfache Beschleunigungslösung wäre es mehrere Seiten parallel zu starten, aber dazu ist einiges an Logik notwendig – ich möchte nur bis zu einer maximalen Anzahl an parallelen Prozessen haben (CPU-Kerne) und benötige die Info wann alle Prozesse fertig sind. Viel Scripting für ein bisschen Geschwindigkeit – und unnötig, denn es gibt ein Passendes Tool: GNU parallel von O. Tange aus „;login: The USENIX Magazine, February 2011:42-47„.
Das Tool ist unter Arch nicht vorinstalliert, findet sich aber im Community-Repo. Der Aufruf ist ähnlich zu xargs – in meinem Fall sieht der Befehl so aus:
parallel -j 8 \
tesseract {} {.}.hocr -l deu hocr \
::: ${files}
In der ersten Zeile wird bestimmt, dass maximal 8 Prozesse zugleich gestartet werden. Danach kommt der Aufruf der Software. {} wird durch den Dateinamen ersetzt, {.} durch den Dateinamen ohne Endung. In der dritten Zeile wird nach dem Trennzeichen (:::) die Dateiliste mitgegeben – in meinem Fall in einer Variable, es kann aber auch direkt per Globbing gearbeitet werden („::: /tmp/out*“).
Der Grundprozess parallel blockt dabei so lange, bis alle Unterprozesse beendet sind – perfekt für meine Anforderung. Durch diese kleine Änderung ist bei mehrseitigen Dokumenten die Verarbeitung um ein vielfaches schneller.
Das Tool ist dabei natürlich nicht auf OCR beschränkt, auch bei anderen Programmen, welche man auf mehrere oder aufteilbare Quellen loslässt, kann es verwendet werden. Ein gutes Beispiel wäre das Umwandeln von Bildern in einer Batch:
parallel -j 8 \
convert {} {.}.png \
::: ./*.bmp
OpenVPN: Kein automatischer Restart nach Verbindungsabbruch
Kurze Verbindungsunterbrechung und weg war er, mein VPN-Tunnel. Soweit nichts besonderes, aber eigentlich sollte OpenVPN die Verbindung automatisch neu aufbauen. In der Praxis funktionierte das Ganze bei mir leider nicht, der Tunnel verschwand einfach, der zugehörige Prozess war nicht mehr auffindbar. Im Log zeigte sich folgendes:
[…server…] Inactivity timeout (--ping-restart), restarting
TCP/UDP: Closing socket
/etc/openvpn/down.sh tap0 1500 1576 …ip… 255.255.255.0 restart
WARNING: Failed running command (--up/--down): could not execute external program
Exiting due to fatal error
/bin/route del -net …gateway… netmask 255.255.255.255
ERROR: Linux route delete command failed: could not execute external program
/bin/route del -net 0.0.0.0 netmask 128.0.0.0
ERROR: Linux route delete command failed: could not execute external program
/bin/route del -net 128.0.0.0 netmask 128.0.0.0
ERROR: Linux route delete command failed: could not execute external program
/etc/openvpn/down.sh tap0 1500 1576 …ip… 255.255.255.0 init
WARNING: Failed running command (--up/--down): could not execute external program
Exiting due to fatal error
Nach kurzem Nachdenken klare Sache: OpenVPN gibt bei Angabe von user/group in der Config nach der initialen Verbindung seine Root-Rechte auf und läuft im spezifizierten Userkontext weiter – und der darf nicht an den Routingtabellen oder Netzwerkgeräten herumfummeln. Die Lösung: Der OpenVPN-User muss rechte zum setzen von Routen behalten oder OpenVPN unter einem höher privilegiertem User laufen.
Scanner-Button unter Arch Linux
Gesehen habe ich sie schon oft, die Hardware-„Scan“-Tasten diverser Scanner – einen wirklichen Sinn haben sie für mich nie ergeben, sind doch üblicherweise Scanner und Tastatur nicht sonderlich weit voneinander entfernt. Nun habe ich für ein autonomes Scansystem einen Raspi ohne Monitor mit Scanner und Scripten verknüpft – wäre praktisch, wenn ich mir jetzt noch die Scan-Taste nutzbar machen könnte, oder?
Das Zauberwort schien erst „scanbuttond“ zu lauten, welches für Arch im AUR verfügbar ist – andere Distributionen scheinen ebenfalls großteils Pakete bereit zu stellen. Nach der Installation kann man mit dem Befehl
scanbuttond -f
prüfen, ob der Scanner unterstützt wird: Das Programm startet kommentarlos im Vordergrund, sollte beim Drücken des Scan-Knopfes jedoch eine passende Meldung erzeugen. Sollte – in meinem Falle leider nicht. Auslöser ist vermutlich die neuere libusb, welche scanbuttond das Gerät nicht finden lässt.
Nach kurzer Recherche fand ich im Arch-Forum den Verweis auf scanbd – ebenfalls im AUR – welches noch aktiv entwickelt zu werden scheint. Die Einrichtung selbst ist in der Arch-Wiki beschrieben. In der Hoffnung dass mein Gerät sofort funktioniert wird der Daemon mit folgendem Befehl gestartet:
scanbd -d 7 -f
Die Ausgaben sind etwas chaotisch, jedoch ist definitiv mein Scannermodell zu erkennen und auch beim Drücken der Scan-Taste ist etwas passendes zu sehen:
scanbd: trigger action for scan for device fujitsu:fi-4120Cdj:13715 with script test.script
[…]
scanbd: append string fujitsu:fi-4120Cdj:13715 to signal scan_begin
scanbd: now sending signal scan_begin
[…]
Entsprechend der Anleitung werden die Dateien kopiert (cp /etc/sane.d/* /etc/scanbd/sane.d/), in /etc/sane.d/dll.conf alles bis auf „net“ gelöscht und in /etc/sane.d/net.conf der Server „localhost“ aktiviert. In /etc/scanbd/sane.d/dll.conf wiederum wird „net“ gelöscht.
Der Scan-Button ist bereits mit /etc/scanbd/test.script vorbelegt, der Einfachheit halber habe ich nur den Inhalt der Datei durch meine Befehle ersetzt. Es wäre auch möglich die zahlreichen Zusatztasten meines Scanners zu nutzen um so bereits einen Speicherort o.Ä. zu definieren oder z.B. den Scan bereits beim einlegen des Papiers zu starten, aber ich belasse es erst mal beim Standard. Unter Arch sollte man nach der Konfiguration noch das Debuglevel in /etc/scanbd/scanbd.conf senken, ansonsten wird das Systemlog durch die sekündlichen Prüfroutinen gut gefüllt.
Dank der kleinen Bastellösung kann ich nun „ohne PC“ scannen – Papier rein, Knopf drücken und der Raspi übernimmt automatisch das einscannen, OCR und archivieren mit (zumindest meistens) brauchbaren Metadaten – der Feinschliff kann dann später am PC erfolgen.
PHP mail(): Sonderzeichen im Betreff richtig Codieren
Na das ist mir noch nie aufgefallen: Offenbar ist die mail()-Funktion von PHP nicht in der Lage deutsche Sonderzeichen im Betreff korrekt zu verarbeiten. Die erste Meldung besagte, dass der Betreff bei einigen Providern verstümmelt ankommen würde. Der IT-Fluch schlug natürlich wieder zu: Sowohl mein Thunderbird als auch K9-Mail und Roundcude zeigten keinen Fehler. Dankenswerterweise brachte dann Amavis die Erleuchtung:
X-Amavis-Alert: BAD HEADER SECTION, Non-encoded 8-bit data (char C3 hex):
Subject: Testm\303\203\302\244il
Argument, so passt das nicht… In den Mailheadern ist das genünschte „ä“ einfach nur als UTF-8-„ä“ vorhanden – E-Mails sind aber üblicherweise nur 7 Bit… Um den Betreff korrekt zu versenden muss man den String vorab mit mb_mime_mimeheader in die richtige Form bringen:
mail('empfang@emfang.em', mb_encode_mimeheader('Testmäil', 'UTF-8', 'Q'), 'Text');
Gentoo-Upgrade: XML::Parser perl module is required for intltool
Uff… Updates schleifen lassen ist bei Rolling-Release-Distros ja immer ein Problem. Heute im Angebot: Das Gentoo-Upgrade eines Systems, welches etwa 4 Monate stand, verabschiedet sich bei nahezu allen Paketen mit folgender Meldung während „configure“:
XML::Parser perl module is required for intltool
Eine Neuinstallation von Perl und dem genannten XML-Modul brachte keine Besserung, auch unter @preserved… oder revdep-rebuild zeigte sich nichts passendes. Die Lösung ist einfacher als befürchtet: Der Befehl
perl-cleaner --reallyall
sucht alle betroffenen Pakete, welche noch Verweise auf ein altes Perl enthalten, und baut sie über portage neu. Bei mir kam es noch zu einer Kollision durch veraltete glib und qt-Pakete, da der emerge-Befehl aber bereits fertig zum kopieren bereitstand war die nötige Ergänzung kein wirkliches Problem – knapp 190 Pakete später funktioniert’s dann auch wieder mit dem Update.
Denon RC-1158 IR-Codes
Um einen AV-Receiver per Arduino zu steuern musste ich – mangels RS232 – die Fernbedienung emulieren. Um das zu bewerkstelligen benötigt man die entsprechenden IR-Codes. Bewaffnet mit IRMP – bzw. dessen Arduino-Umsetzung – habe ich mir die entsprechenden IR-Command-Codes der Fernbedienung notiert. Wers braucht: Viel Spaß.
|
DENON RC-1158 Mapping |
|||
|
Florian „adlerweb“ Knodt · 2014 · www.adlerweb.info |
|||
|
Protokoll: DENON/Sharp · Address: 0x3254 |
|||
|
StBy |
On |
||
|
0x4003 |
0x4002 |
||
|
Sleep |
Dimmer |
Status |
Search |
|
0x4344 |
0x4290 |
0x4280 |
0x43D7 |
|
BD |
TUNER |
BAND |
MEMORY |
|
0x42D1 |
0x42CF |
0x43D0 |
0x4024 |
|
DVD |
DOCK |
SHIFT |
MODE |
|
0x42D0 |
0x42DC |
0x43CE |
0x43D3 |
|
TV |
GAME |
CH+ |
TuneUp |
|
0x42D2 |
0x42D5 |
0x43CC |
0x43CA |
|
SAT/CBL |
V.AUX |
CH- |
TuneDn |
|
0x42D3 |
0x42D9 |
0x43CD |
0x43CB |
|
Q_CD |
Q_BD |
Q_GAME |
Q_AUX |
|
0x4124 |
0x4125 |
0x4126 |
0x4127 |
|
MENU |
AUDIO ADJ |
VolUp |
|
|
0x4023 |
0x41C0 |
0x4170 |
|
|
Up |
|||
|
0x401B |
|||
|
Left |
Enter |
Right |
|
|
0x401D |
0x401F |
0x401E |
|
|
Down |
|||
|
0x401C |
|||
|
CH LEVEL |
RETURN |
VolDn |
|
|
0x417A |
0x4022 |
0x4171 |
|
|
NIGHT |
RESTORER |
TONE |
MUTE |
|
0x4222 |
0x4224 |
0x4196 |
0x4172 |
|
SURR_LEFT |
SURR_RIGHT |
DELAY- |
DELAY+ |
|
0x414C |
0x4150 |
0x426E |
0x426D |
|
IPOD_SKIP_L |
IPOD_STOP |
IPOD_PLAY |
IPOD_SKIP_R |
|
0x2005 |
0x2008 |
0x2001 |
0x2004 |
|
IPOD_REV |
IPOD_REPEAT |
IPOD_RANDOM |
IPOD_FWD |
|
0x2016 |
0x2011 |
0x2010 |
0x2015 |
rtl_fm: Frequenzanzeige im Scan-Modus
Kurzer QnD-Patch zwischendurch: Möchte man mit einem RTL_SDR mehrere Frequenzen mit wenig Verkehr im Auge behalten bietet es sich an rtl_fm im Scan-Modus zu nutzen. Hierbei klappert er alle angegebenen Frequenzen ab und bleibt bei erreichen einer einstellbaren Schwelle auf dem aktuellen Kanal stehen. Von der Funktion her ähnlich wie der automatische Sendersuchlauf moderner Radios nur mit dem unterschied, dass bei Signalverlust (aka. Gegenstelle sendet nicht mehr) der Scan weitergeht. Leider hat rtl_fm hier einen Nachteil: Man sieht nicht was er tut – zwar bekommt man das Signal, kann aber nicht wirklich feststellen von welcher Frequenz es stammte. Mit folgendem Patch wird das Tool um das Argument „-v“ ergänzt. Hiermit gibt der Scan-Modus erweiterte Meldungen über den Zustand aus, namentlich „Scan…“ wenn kein Signal vorhanden ist und „Tuned to 12345Hz“ wenn er sich auf ein Signal eingependelt hat. Die Ausgaben erfolgen über stderr und beeinträchtigen daher nicht den eigentlichen Audiostrom.
Disclaimer wie üblich: Ich bin nicht wirklich im C-Bereich unterwegs, der Code könnte möglicherweise Fehler enthalten welche euren Rechner in ein katzenfressendes Monster verwandeln.
Arch Linux: tmpfs-Bootfehler nach Systemd-Upgrade
War ja klar – gerade erst vom 30c3 zurück und schon die ersten Probleme: Auf meinem Hauptrechner hatte ich vor Abfahrt noch schnell ein Update gemacht, welches auch Systemd betraf. Bei jetzt erfolgtem, ersten Start nach dem Update hing sich das System im Bootvorgang auf:
timed out waiting for device tmpfs.device
Ursache war eine Performanceoptimierung meinerseits: /tmp liegt nicht auf einem Datenträger sondern per tmpfs im RAM. Offenbar war ich aber damals etwas zu schnell bei Copy&Paste, denn meine /etc/fstab-Zeile sah so aus:
tmpfs /tmp tmpfs defaults,nodev,nosuid 0 1
Die letzte 1 besagt, dass das System ein fsck, also Dateisystemcheck, beim Boot durchführen soll. Bisherige Systemd-Installationen ignorierten die Angabe, da tmpfs einerseits beim Boot leer ist und andererseits kein fsck-Befehl für dieses virtuelle Dateisystem existiert. Mit der neuen Version tritt obiger Fehler auf. Fix ist recht einfach: Per Boot-CD oder ohne init.d starten (init=/bin/bash als Kernel-Argument), die Root-Partition schreibbar mounten (mount -o rw /dev/sd** /mnt bzw mount -o remount,rw /) und in der /etc/fstab die letzte 1 der tmpfs-Zeile(n) gegen eine 0 ersetzen.
Linux auf Acer Aspire One ZG5: Kernel-Panic durch SD-Leser
Offenbar gibt es eine Regression in den letzten Linux-Kerneln(vermutlich 3.12.x): Auf oben genannten System kam es alle paar Minuten zu unerklärlichen Kernel-Panics. Im Trace war öfter die Rede vom sdhci-Modul, welches für die SD-Leser zuständig ist. Auslöser ist höchstwahrscheinlich der Slot an der linken Seite – die rechte Seite nutzt PCI-Hotplug und ist ohne Karte dem System nicht bekannt. Betroffen sind vermutlich beide Seiten, zwar ist der rechte durch PCI-Hotplug ohne Karte von System getrennt, jedoch werden beide Controller als „JMicron Technology Corp. Standard SD Host Controller“ erkannt.
Als Workaround kann man – bis der Fehler behoben ist – den SD-Card-Leser abschalten, hierzu wird folgendes Kernel-Argument genutzt:
modprobe.blacklist=sdhci,sdhci_pci
Im Fall von Grub2 auf Archlinux kann es z.B. in /etc/defaults/grub als GRUB_CMDLINE_LINUX hinterlegt werden. Logischerweise lassen sich bis der Fehler behoben ist keine SD-Karten im Gerät nutzen.