Posts Tagged ‘Terminal’

Freitag, 30. März 2018

Zwei Tipps zu dd unter macOS

dd verwendet man unter macOS wahrscheinlich normalerweise dann, wenn man Images (1:1 Abbilder) von portablen Datenträgern machen möchte oder diese auf portable Datenträger zurückspielen möchte.

Folgende zwei Dinge sind dabei wichtig:

Geschwindigkeit

Unter macOS sollte man Datenträger immer in der Schreibweise /dev/rdisk1s1 ansprechen und nie als /dev/disk1s1. Damit können Images messbar schneller geschrieben werden, in der Regel mit Faktor 3.

Auch die Blocksize (definiert mit dem Parameter bs) sollte hoch angesetzt werden — nachfolgend auf 2 Megabytes:

# dd if=/tmp/image.img of=/dev/rdisk1 bs=2m

Zwischenstand

Leider gibt dd im normalen Gebrauch keinen Fortschritt aus. Erst sobald der Kopiervorgang abgeschlossen ist, erhält man eine Statistik über die Anzahl der kopierten Blöcke sowie über den Datendurchsatz.

Betätigt man aber bei einem in der Shell laufenden dd-Kopierprozess die Tastenkombination Ctrl-T gibt dd den Zwischenstand des Lese- oder Schreibvorgangs aus, ohne den Kopiervorgang zu unterbrechen.

Tags: , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 30. April 2015

Duplikate und Müll aus OS Xs „Open with“ Menu entfernen

Folgender Befehl bewirkt eine gehörige Entschlackung des Menus:

# /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain user
# killall Finder

Quelle: Remove Duplicates from the “Open With” Right-Click Menu in Mac OS X

Tags: , , ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Donnerstag, 26. März 2015

monit unter Mac OS X neu starten

Vor einigen Tagen meldete mir die monit-Instanz aus einem anderen Subnet, dass die Web-Oberfläche der monit-Instanz auf meinem Mac mini nicht mehr ansprechbar war. Heute, nach unzähligen Warnmeldungen, habe ich mich um das Problem gekümmert.

Wie sich herausstellte, liess sich das Problem beheben, indem ich monit schlicht neu startete. Auf der Mac OS X-Kommandozeile geht dies so:

$ sudo launchctl unload /Library/LaunchDaemons/com.tildeslash.monit.daemon.plist
$ sudo launchctl load /Library/LaunchDaemons/com.tildeslash.monit.daemon.plist

Via: Monit

Tags: , , , , , , , ,
Labels: Linux

Keine Kommentare | neuen Kommentar verfassen

Samstag, 29. März 2014

Die Datei mach_kernel im Finder ausblenden

Aus einem mir unerklärlichen Grund wird bei mir die Datei mach_kernel, welche den Mac OS X Kernel enthält, im Finder angezeigt:

mach_kernel
image-5799

Mit folgendem Shell-Befehl wird die Datei im Finder inskünftig ausgeblendet:

# chflags hidden /mach_kernel

Via: mach_kernel now visible

Tags: , , , ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Mittwoch, 25. September 2013

Das Mac OS X Terminal mit dem aktuellen Finder-Pfad öffnen

Wer sich fliessend zwischen den zwei Welten — dem OS X GUI und dem Unix-Terminal — bewegt, wird die Minimalapplikation Go2Shell äusserst nützlich finden. Nachdem man sie als Button in die Finder Button-Leiste gezogen hat, kann man auf Knopfdruck das Mac OS X Terminal (Unix-Shell) öffnen und findet sich im selben Ordner wieder, welchen man gerade im Finder sieht.

Die umgekehrte Variante sei hier selbstverständlich auch noch am Rande erwähnt:

$ open .

öffnet ein Finder-Fenster mit dem Verzeichnis, in welchem sich der Shell-Benutzer gerade befindet.

Tags: , , , , , ,
Labels: Apple

Keine Kommentare | neuen Kommentar verfassen

Sonntag, 3. März 2013

Arte-Videos herunterladen

Vor ein paar Tagen hat arte die Dokumentation Staatsgeheimnis Bankenrettung veröffentlicht. Man kann die Reportage unter dem genannten Link live anschauen.

Wer sich die Dokumentation aber auf die lokale Festplatte laden möchte, um sie danach beispielsweise mit Air Video Server und Air Video.app unter iOS auf den Apple TV zu streamen, muss auf der Kommandozeile aktiv werden:

  1. # port install rtmpdump
  2. Download von Florian Crouzats Shell-Script mittels
    $ wget http://files.floriancrouzat.net/ripArte-v0.9.sh
  3. $ chmod 755 ripArte-v0.9.sh
  4. $ ripArte-v0.9.sh "http://videos.arte.tv/de/videos/staatsgeheimnis-bankenrettung--7340782.html"
  5. Auswahl des vierten RTMP Streams (German High-definition RTMP, rtmp://artestras.fcod.llnwd.net/a3903/o35/mp4:geo/videothek/ALL/arteprod/A7_SGT_ENC_04_048116-000-A_PG_HQ_DE?h=24fceb3242c5803955ac67b8b44ce499)

Und das Resultat sieht folgendermassen aus:

...
340386.493 kB / 3129.09 sec (99.9%)
Download complete

Tags: , , , , ,
Labels: IT, Medien

3 Kommentare | neuen Kommentar verfassen

Donnerstag, 14. Februar 2013

Data Mining mit Ubuntu, MySQL, PHP und Python

Beruflich setze ich mich derzeit mit der Analyse von Inhalten von Web-Sites auseinander. Nachfolgend habe ich einige Erfahrungen aufgelistet, welche ich dabei gemacht habe.

Wir verarbeiten in diesem Projekt Web-Sites, welche wir mit entsprechenden Tools aus dem Web auf den lokalen Rechner gespiegelt haben. Die Web-Site Assets liegen im Dateisystem. Zur Weiterverarbeitung der Daten wurden die HTML-, JS-, CSS- und XML-Rohdaten in eine MySQL-Tabelle gespitzt (12GB) und anschliessend mit Meta-Daten ergänzt.

Ich persönlich bin nicht sicher, ob die Ablage von HTML-Code in der Datenbank die sinnvollste und performanteste Lösung ist, aber dies war nunmal der Stand des Projektes als ich dazu gestossen bin — und daran liess sich nichts mehr rütteln.

Da wir unter anderem auch Volltextsuchen auf die Grunddaten anwenden, hätte ich mir Apache Solr genauer angeschaut und darauf mittels PHP und JSON zugegriffen.

Kommandozeile

Da der Ubuntu-Server aus mir unerfindlichen Gründen mit LAMPP aufgesetzt wurde, befinden sich die Binaries wie php nicht in den Standardpfaden und werden von bash ohne absolute Pfadangabe nicht gefunden. Da man den Interpreter täglich dutzende, wenn nicht gar hunderte Male aufruft, ist es ratsam, das Verzeichnis sofort in die $PATH-Variable des Shells aufzunehmen.

Hier findet man sich in der Shell Startup File Hell wieder. Je nachdem, ob man lokal arbeitet oder sich per SSH einloggt muss der Befehl an einem anderen Ort stehen. Schlussendlich habe ich die nachfolgende Zeile …

...
PATH="$PATH:/opt/lampp/bin"

… ans Ende folgender zwei Dateien angefügt:

  • ~/.profile
  • ~/.bashrc

Datenbank (MySQL)

Cache aktivieren

Wir führen PHP-Scripts über die Linux-Shell aus. Gerade bei der Entwicklung neuer Scripts sind verschiedene Anläufe nötig, bis alle Bugs und nicht beabsichtigten Funktionen ausgemerzt sind. Da wir oftmals an einem Datenset von 60’000+ Seiten arbeiten, ist es unabdingbar, dass wir eine Cacheing-Lösung anwenden, um Datenbankabfragen im Kurzspeicher zwischenzulagern.

Folgende Parameter in my.cnf aktivieren den in MySQL vorhandenen Cache:

...
[mysqld]
...
query_cache_type = 1
query_cache_size = 512M
query_cache_limit = 32M

Der Geschwindigkeitsgewinn ist immens — nachdem ein Script mit SELECT-Statements zum ersten Mal ausgeführt wurde und dafür mehrere Minuten benötigte, rauscht es in den folgenden Malen innert Sekunden durch.

Programmierung (PHP und Python)

Helper-Funktionen und -Klassen

Wie aus der Web-Entwicklung gewohnt sollte man bei jedem der mit der Zeit entstehenden Scripts zu Beginn Klassen, allgemeine Einstellungen und Funktionen einbinden.

In der Funktionsbibliothek setze ich beispielsweise folgende wichtigen Parameter in globaler Form:

...
error_reporting(E_ALL);
date_default_timezone_set('Europe/Zurich');

Auch die Datenbankverbindung wird mittels meiner MySQL-Klasse hier erstellt und an alle Scripts weitergegeben, welche die Library einbinden.

Aufbau der Scripts

Als ich zum Projekt stiess herrschten Spaghetti-Code in teils monolithischen Scripts vor. Ich habe meine eigenen Scripts dann aber so entwickelt, dass sie dem Unix-Gedanken folgend normalerweise nur eine bestimmte Funktion ausführen, diese dafür aber ausgezeichnet und in sich abgeschlossen. So steht im Normalfall in jedem Script, welches Daten manipuliert, zuoberst ein SQL-Query, welches die zu verändernden Datenbankdaten auswählt.

Bei der Entwicklung wählt man hierbei ein Query, das einen oder nur wenige Werte aus der Datenbank ausliest und verarbeitet — in dieser Phase hat man keine Zeit, möglicherweise fehlerhafte Manipulationen an 60’000+ Seiten durchzuführen.

HTML mit regulären Ausdrücken parsen?

Nein, besonders nicht dann, wenn man konkret an Eigenschaften des SGML-Markup interessiert ist (bspw. Wohin zeigen Links?). Hierzu verwendet man die in PHP standardmässig enthaltene DOMDocument-Bibliothek.

Wichtig ist, dass man bei der Verwendung von E_ALL die loadHTML()-Funktion mittels @ stummschaltet, weil sonst das Terminal mit Warnungen über fehlerhaften HTML-Code (leider an der Tagesordnung) vollgespamt wird:

...
$dom = new DOMDocument();
@$dom->loadHTML($html);
$elements = $dom->getElementsByTagName('a');

HTML manipulieren — und Fallstricke

Für jede HTML-Seite erstellen wir eine Nur-Text-Version. Hierzu verwenden wir html2text.py von Aaron Swartz selig. Bevor das HTML aber umgewandelt wird, säubern wir die HTML-Datei auf eigene Faust. Auch hier kommt DOMDocument zum Zug.

Wir suchen dabei zuerst einmal Elemente jeglicher Art, deren ID oder Klasse den String nav, menu und breadcrumb enthält. Die Navigation interessiert uns nämlich nicht, und noch schlimmer: Sie verfälscht teilweise die Resultate, weil in der Navigation gesuchte Begriffe vorkommen.

Hierzu lade ich den HTML-Code wieder in eine DOMDocument und iteriere danach über alle Elemente auf der Suche nach den besagten IDs und Klassennamen:

function cleanNavMenuElements($html = null) {
		$dom = new DOMDocument();
		@$dom->loadHTML($html);
		
		$changesMade = false;
		
		$elements = $dom->getElementsByTagName('*');
		foreach($elements as $element) {
			if(preg_match('/^(html|body)$/',$element->nodeName)) {
				// Otherwise we might delete the whole DOM!
				continue;
			}
			
	        if($element->hasAttribute('class') && preg_match('/(nav|menu|breadcrumb)/i',$element->getAttribute('class')) > 0) {
				status('Found element with class ' . $element->getAttribute('class'));
				$element->parentNode->removeChild($element);
				
				$changesMade = true;
				
				// Don't go further if we removed this node already
				continue;
			}
			
			if($element->hasAttribute('id') && preg_match('/(nav|menu|breadcrumb)/i',$element->getAttribute('id')) > 0) {
				status('Found element with id ' . $element->getAttribute('id'));
				$element->parentNode->removeChild($element);
				
				$changesMade = true;
			}
	    }
		
		if(!$changesMade) {
			return $html;
		}
		
		return $dom->saveHTML();
	}

Ein Problem manifestiert sich bei der Manipulation aber: Jegliche Anpassungen erfolgen live, was verwirrende Folgen für Schleifen haben kann.

Da die Suche nach obigen ID- und Klassennamen nicht alle Navigationselemente eliminiert, suche ich in einem zweiten Anlauf Tabellen und Listen, deren Elemente ausschliesslich Links enthalten. Dies ist ein guter Indikator, ein Navigationsblock gefunden zu haben.

Hier ist das Problem des sich bei jeder Iteration veränderndem DOM aber sehr ausgeprägt. Wenn ich deshalb durch td-Elemente und li-Elemente iteriere, verwende ich nicht foreach() sondern eine for()-Schleife, deren Counter $i ich immer dann zurücksetze, wenn ich ein Element entferne. Ansonsten wird aus Erfahrung in der Folge eines (oder mehrere Elemente) übersprungen. Damit dies klappt, arbeite ich den DOM Tabellen- respektive Listenweise ab:

$containers = $dom->getElementsByTagName($containerTag);
	
foreach($containers as $container) {
	$items = $container->getElementsByTagName($itemTag);
	
	for($i = 0; $i < $items->length; $i++) {
		$item = $items->item($i);
		
		if($item === null) {
			continue;
		}
		
		$otherTagsPresent = false;
		foreach($item->childNodes as $child) {
			$tag = $child->nodeName;

			if($tag == '#text') {
				$text = trim($child->nodeValue);
				$len = strlen($text);
				if($len < 1) {
					//#text is empty, thus not relevant
					continue;
				}
			}

			if($tag != 'a') {
				$otherTagsPresent = true;
				continue;
			}
		}

		if(!$otherTagsPresent) {
			$item->parentNode->removeChild($item);
			$i = $i-1;
		}
	}

Weiterverarbeitung der Daten durch Nicht-IT-Profis

Zur Weiterverarbeitung der Auswertungen durch andere, in IT nicht versierte Mitarbeiter habe ich eine Funktion geschrieben, welche eine Pfadangabe sowie CSV-Daten als Argumente übertragen erhält. Die Datei wird geschrieben und gleich anschliessend mittels eines kleinen Python-Scripts (Stichwort: openpyxl) in das bei uns hauptsächlich verwendete XLSX-Format konvertiert.

Tags: , , , , , , , , ,
Labels: Programmierung

Keine Kommentare | neuen Kommentar verfassen

Samstag, 24. November 2012

Text in PDFs greppen

Da haben also die SBB einen Wettbewerb online, welcher die Eingabe von Ticketnummern erfordert. Und gleichzeitig habe ich Quittungen von über SBB Mobile georderte Tickets für Geschäftsreisen auf meinem Computer abgelegt.

Was macht man da? Richtig, man filtert die PDFs nach den geforderten Ticket-Nummern, und zwar so:

pdftotext

Ich gehe davon aus, dass jeder Terminal.app-Hacker macports installiert hat

Man benötigt zuerst einmal das in xpdf enthaltene Tool pdftotext:

# port install xpdf-tools

Shell-Magic

Nachdem das Tool installiert ist, navigiert man in den Ordner, welcher die PDFs enthält und gibt folgenden Befehl ein:

$ for i in *.pdf; do pdftotext "$i"; done;

Die in PDFs enthaltenen Textzeichen werden extrahiert und automatisch in eine Textdatei mit Endung .txt gespeichert, welche denselben Basename trägt wie die PDF-Datei.

Nun kann ich problemlos greppen:

$ cat *.txt | grep "OT"

… und schon erhalte ich eine schöne Liste in der Form

OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000
OT 0000 0000 0000

Tags: , , , , , , ,
Labels: IT

1 Kommentar | neuen Kommentar verfassen

Sonntag, 18. November 2012

Wieso Mac OS X aus seinem Schlaf aufwacht

$ syslog | grep -i "Wake reason"

Quelle: Determine Why Your Mac Wakes Up From Sleep

Tags: , , , ,
Labels: Apple

1 Kommentar | neuen Kommentar verfassen

Sonntag, 18. November 2012

Adobe Source Code Pro: Quelloffene Programmierer-Schrift

Adobe überrascht für einmal und offeriert mit Source Code Pro eine quelloffene OTF-Schrift, welche speziell für Entwickler geeignet ist, welche eine leicht lesbare Monospace-Schriftart benötigen.

Wer das Ding kompilieren möchte, kann sich an Adobes Git-Repository vergnügen:

adobe / source-code-pro

Alle anderen laden sich das OTF-Binary von hier herunter:

Free Font Source Code Pro by Adobe

Nicht mit Apple Terminal

Leider unterstützt Apples Terminal.app unter Mac OS X 10.7 keine OTF-Fonts:

Terminal.app won’t display OpenType fonts (.otf)

Mist! Dann verwende ich die Schrift halt nur in TextMate … Als Ersatz kommt in Terminal.app Microsofts Consolas zum Einsatz.

Tags: , , , , , , , , , ,
Labels: IT

Keine Kommentare | neuen Kommentar verfassen