JavaScript Data-Watchpoints

Jeder der eine größere Anwendung debuggt, wird sich schnell in einer Situation wiederfinden, in der einfache Breakpoints nicht mehr ausreichen um die Ursache des Fehlers zu finden. Die meisten modernen Debugger beherrschen deswegen das Setzen von Watchpoints.
Watchpoints beobachten eine Variable und halten die Ausführung des Programmes an, sobald sich der Wert der Variable ändert. Auch wenn die Entwicklertools der meisten Browser ziemlich fortgeschritten sind, sucht man Watchpoints hier jedoch vergeblich. Glücklicherweise gibt es ein paar Möglichkeiten um dieses Dilemma herumzuarbeiten, indem man die Watchpoints direkt in JavaScript oder der Konsole setzt:
Gecko-basierte Browser wie Firefox bieten die Möglichkeit die Watchpoints mit der Funktion Object.prototype.watch() direkt in der Debugging-Konsole zu setzen.

var someVar = { myProperty: 'foo' };
Object.watch('myProperty', function () {
   console.log('myProperty changed!');
});

Chrome besitzt das noch mächtigere Object.observe(), mit dem man beliebige Variablen beobachten kann und nicht nur Member von Objekten.

var someVar = ...
Object.observe(someVar, function () {
   console.log('someVar changed!');
});

Für alle anderen Browser gibt es einen Polyfill, der den Objekt-Prototyp mit einer neuen Funktion .watch() erweitert.
Als i-Tüpfelchen kann man nun noch den Debugger halten lassen sobald der gesetzte Watchpoint ausgeführt wird. Hierfür verwendet man im Callback das Statement debugger; welches in nahezu allen Browsern funktioniert.

Object.observe(someVar, function (name, object, type, oldValue) {
    debugger;
});

Git Bisect, oder die verdrehten Tricks der Kernel-Hacker

Wer häufiger in Projekten mit mehreren Entwicklern auf Jagd nach Bugs gehen muss, hat sicher häufig das Problem dass einige Fehler als Nebeneffekte anderer Patches oder Änderungen auftreten können.
Als ich diese Woche dabei war ein einen Bug in der Browser-History in Icingaweb2 zu fixen hatte ich ein vergleichbares Problem: Ich wusste zwar dass ein Fehler früher einmal auftrat der im aktuellen Master nicht mehr auftritt, aber nicht durch welche Änderung der Fehler dann letztendlich beseitigt wurde. Mein bisherigen Ansatz war in diesem Fall einfach zu einem beliebigen verdächtigen Commit in der Mitte auszuchecken und dann einfach zu testen. Wenn der Fehler dort noch auftritt, dann wusste ich zumindest dass der Commit, der den Fehler dann tatsächlich gefixt hat in einem späteren Commit auftritt. Nachteil dieser Technik ist natürlich dass man mühsam die Commit-History durchsuchen muss um manuell einen geeigneten Commit auszuwählen.
Ein Kollege hat mich dabei beobachtet und mich dann freundlicherweise darauf hingewiesen dass es auch wesentlich einfacher geht. Git hat nämlich für diesen Fall tatsächlich eine eingebaute Funktion namens Git-Bisect. Laut Dokumentation führt Git-Bisect eine Binärsuche durch um eine Änderung zu finden, die einen bestimmten Bug einführt, also vergleichbar mit meinem bisherigen Ansatz, aber mit dem kleinen Unterschied dass GIT die Commits automatisch auswählt und auscheckt.

Beispiel

Ich beginne damit an einen Punkt auszuchecken, an dem der Fehler auftritt. Wie man es noch aus der Schulzeit kennt braucht man an dieser Stelle jetzt allerdings ein bisschen Transferleistung um auf die Lösung zu kommen: Git-Bisect sucht nämlich einen Patch der einen Fehler einführt, ich suche aber nach etwas das den Fehler behebt. Deshalb muss ich im Folgenden gute und schlechte Commits verdrehen um das Feature für meinen Zweck nutzen zu können.
Ich starte den Vorgang und markiere den kaputten Commit also demnach mit good.

   git bisect start
   git bisect good

Anschließend markiere ich den aktuellen Master als bad, da ich ja weiß dass der Fehler dort schon gefixt wurde.

   git bisect bad master

Jetzt ist Git bereits zum Commit genau in der Mitte gesprungen und gibt sogar aus wie viele Schritte noch zu tun sind um den Fehler zu finden.
start
An dieser Stelle starte ich jetzt Icinga Web 2 und überprüfe ob der Fehler noch vorhanden ist. Da der Fehler an dieser Stelle nicht mehr auftritt markiere ich den Commit als bad.

    git bisect bad

Git springt wieder an einen neuen Commit und ich wiederhole den selben Schritt. Wenn der Fehler auftreten sollte markiere ich den Commit als gut und fahre ansonsten wie gehabt fort.

    git bisect good

Am Ende des ganzen Prozesses spuckt einem Git den ersten bad Commit aus, also den ersten Commit an dem der Fehler auftritt (oder in unserem Fall eben nicht mehr). Allerdings haben wir jetzt das Problem dass der Commit auf einen größeren Merge-Commit zeigt, was leider noch relativ wenig hilfreich ist. Um dieses Problem zu lösen starte ich den ganzen Prozess noch mal und nehmen diesmal den ersten und letzten Commit des Merge-Commits als Start und Ende.

    git bisect reset; git bisect start
    git bisect bad LETZTER_COMMIT
    git bisect good ERSTER_COMMIT

schluss
Endlich spuckt uns Git den Commit aus der den Fehler dann tatsächlich behoben hat, eine Änderung am Caching unserer Browser-History.

Fazit

Aus Sicht der Linux-Kernel-Hacker, für die Git ja ursprünglich entwickelt wurde, macht so ein Feature definitiv Sinn, denn ein großes verteiltes Projekt wie der Linux-Kernel ist sicher ein Garant für lange Abende der Fehlersuche in großen Commit-Histories. Jedoch kann oft auch jedes andere Projekt von diesen Features profitieren, wenn man denn davon weiß. Wie immer gilt: es lohnt sich seine Tools zu beherrschen und sich mit seinen Kollegen darüber auszutauschen, vielleicht existieren ja Tricks an die man noch nicht einmal gedacht hat!

Visual Studio Code für Node.js unter Linux ausprobiert

Wenn man es genau nimmt hätte dieses Jahr ja eigentlich die Hölle zufrieren müssen, denn Microsoft hat tatsächlich einen Ableger von Visual Studio für Linux veröffentlicht: den Texteditor Visual Studio Code. Bei VSCode handelt es sich allerdings um keinen vollwertigen IDE, wie man beim Namen eigentlich vermuten könnte, sondern um einen Texteditor, der aber immerhin einen Debugger, Autocompletion und GIT-Support mitbringt. Der Editor untersützt C#, HTML, CSS, JS und Node.JS.
Da ich für das Projekt NETRP Node.JS mit dem Express-Webserver verwende und dafür schon länger auf der Suche nach einem guten Editor bin, habe ich die Preview-Version des Microsoft-Editor gleich mal ausprobiert. Meine Erfahrungen dabei möchte ich euch nicht vorenthalten.

Installation

Die Installation ist denkbar einfach und besteht daraus ein Zip zu entpacken und das Binary im Programmordner auszuführen.

Autocompletion

Wie bei anderen Texteditoren, muss man in VSCode keine Projekte anlegen, sondern öffnet einfach den Ordner im Editor. Wenn man eine beliebige JavaScript-Datei öffnet funktioniert grundlegende Autocompletion, Compiler-Warnungen und das Syntax-Highlighting bereits automatisch.
Ohne jegliche Konfiguration kennt die Autocompletion aber momentan nur die Symbole die direkt im Code definiert wurden oder die Built-In-Objects. Beim Hovern über ein unbekanntes Symbol wird einem aber gleich ein Quick Fix angeboten um dieses Problem zu beheben: VSCode fragt im Hintergrund die Datenbank Definitely Typed ab, die Typskriptdefinitionen für sehr viele übliche JavaScript-Libraries bereitstellt. Diese Dateien können dann direkt in eingebunden und vom Autocompleter verwendet werden um das Interface der verfügbaren Funktionen nachzuschlagen.

Debugging

Fürs Debuggen benötigen wir mindestens die Version 3.12 der Mono-Runtime. Da ich aber noch Fedora20 verwende und es hier im Repository relativ düster aussieht, installiere ich die Version direkt vom Mono-Project.
Die Dokumentation von VSCode sagt uns, dass wir zuerst launch.json auf den Einstiegspunkt zeigen lassen müssen, bei NETRP liegt diese Datei in: src/netrp_server/netrp.js. Die launch.json wird automatisch generiert und ins Projekt eingefügt, sobald man die Debugging-Konfiguration des erste mal öffent.
Der Dokumentation zu folge, sollte nach F5 jetzt eigentlich bereits die Anwendung und den Debugger starten, stattdessen überrascht VSCode mit dem wenig aussagekräftigen Fehler “Connection failed“.
connection-failed
Eventuell existiert irgendein Problem mit der Run-Konfiguration, aber aufgrund der fehlenden Fehlerbeschreibung versuche ich lieber einfach direkt einen anderen Ansatz: den Debugger an den vorhandenen Prozess anhängen. Wenn man die Anwendung mit node –debug-brk netrp selbst startet und den Debugger stattdessen über einen TCP-Port and den Prozess anhängt, funktioniert es auch schon einwandfrei:
VSC - Debugger
In der aktuellen Vorabversion unterstützt der Debugger nur die typischen Kernfeatures, also das Setzen von Breakpoints und das manuelle Stepping. Zumindest in der Linuxversion wirkt das Stepping in der Preview aber noch etwas träge und es gibt ein spürbare Verzögerung beim Bedienen des Debuggers.

Git

Das Git-Repository wird automatisch erkannt und der Reiter “Git” zeigt alle Änderungen an. Es ist möglich komplette Dateien zu stagen und Commits zu erstellen, für feinere Aktionen ist weiterhin die CLI notwendig.
git

Fazit

Der Editor lässt sich schnell einrichten und verwenden und besonders das einfache beschaffen von TypeScript-Definitionen für JS-Libraries hat mich beeindruckt. Sobald das Projekt in einer finalen Version ist werde ich es wohl definitiv als Editor für meine Node-Projekte in Betracht ziehen.

I hate reading other peoples code

Machen wir uns nichts vor, als Entwickler verbringt man oft mehr Zeit damit sich vorhandenen Quellcode durchzulesen, als tatsächlich Neuen zu schreiben. Beim lesen so mancher unbekannter Codebasis mit mangelhafter Dokumentation hat man natürlich noch Glück, wenn man sich dabei nicht wie in diesem Webcomic vorkommt. Umso wichtiger ist, dass man gute Mittel kennt um sich schnell mit einer großen Codebasis vertraut machen zu können und um einem diese mühselige Arbeit wenn möglich zu ersparen.

Überblick verschaffen

Ein klassicher Ansatz ein unbekanntes Programm zu verstehen, ist es einfach dieses auszuführen und sich dabei den Quellcode anzusehen. Oft hilft das jedoch nicht wirklich den größeren Zusammenhang und die Struktur des Programmes zu ergründen, da man immer nur eine Funktion / Klasse auf einmal betrachten kann. Zum Glück bieten viele IDEs wie NetBeans oder PHPStorm die Möglichkeit Diagramme für genau diesen Zweck zu generieren.

UML-Klassendiagramme

Wenn man in PHPStorm beispielsweise eine Klasse selektiert und auf “Show Diagram” drückt, wird automatisch ein Klassendiagramm generiert, mit dem man sich einen schnellen Überblick über vorhandene Datentypen und Vererbungshierarchien verschaffen kann.

PHPStorm-UML-Klassendiagramm

Ein UML-Klassendiagramm der Icingaweb2-Charting-Library

Zustands- und Sequenzdiagramme

Besonders bei Webanwendungen kann es aber sinnvoll sein Teile der Funktionen als Sequenz- oder Zustandsdiagramm darzustellen. Solche Diagramme lassen sich leider meistens nicht so einfach aus Quellcode generieren, bieten aber besonders deswegen oft eine Neue/Alternative Sicht auf das was im Programm passiert und können deshalb das Verständnis des Codes erleichtern. Zum modellieren dieser Diagrammtypen gibt es eine Reiher kostenloser Webtools wie Gliffy oder draw.io.

Ausprobieren

Wenn man einfach nur herausfinden will was ein Programm in einer bestimmten Situation macht, geht Probieren oft über Studieren.

strace

Strace listet auf, welche Systemcalls ein Programm aufruft. Mit strace -c <app>  kann man sich eine Zusammenfassung aller Systemaufrufe ausgeben lassen. Wenn man z.B. einfach wissen will welche Dateien ein Programm öffnet, kann man Strace mit dem Parameter -e trace=open starten, und bekommt alle Aufrufe des Linux-Systemcalls open aufgelistet.

Prozesse mit strace untersuchen

Prozesse mit strace untersuchen

Profiling

Ein Profiler verrät einem bekanntermaßen womit ein Programm die meiste Zeit verbringt. Das ist nicht nur hilfreich um Performance-Bottlenecks zu finden, sondern auch um herauszufinden welche Funktion wie oft aufgerufen wird. Für Webanwendung mit PHP lassen sich mit XDebug profilen und können in IDEs wie PHPStorm dargestellt werden.

Sonstige Möglichkeiten

In einem älteren Blogpost, hatte ich die D3 JavaScript-Library “Code-Flower” vorgestellt, die einem eine Übersicht über die Größe (LOCs) einzelner Klassen im Quellcode gibt. Auch wenn das Ergebnis vor allem optisch eindrucksvoll ist, kann die Library in Verbindung mit Versionskontrollen genutzt werden um eine Historie über die zeitliche Entwicklung des Quellcodes zu generieren.
Die verschiedenen Möglichkeiten Programme zu untersuchen sind eigentlich fast nur durch die eigene Kreativität eingeschränkt. Es gibt unzählige Debugging und Analysetools, die sich mit ein wenig Einfallsreichtum dazu verwenden lassen können um ein Programm zu untersuchen auch ohne sich jede Codezeile durchzulesen.

Icinga Web 2 Source-Code-Flower

Um sich schnellen Überblick über eine große Menge Code zu verschaffen, kann es sinnvoll sein dazu grafische Tools zu verwenden. Eine Möglichkeit, die dazu auch noch ziemlich eindrucksvoll aussieht, ist mit der JavaScript-Library CodeFlowers den gesamten Quellcode als interaktive Baumstruktur darstellen zu lassen.
Eine Live-Demo mit einer Code-Flower von Icinga Web 2 befindet sich hier. Neben dem aktuellen Stand könnt ihr dort auch einige ältere Snapshots auswählen, sodass ihr die die verschiedenen Entwicklunggstände über die letzten eineinhalb Jahre miteinander vergleichen könnt.
Auf der Seite befindet sich die detaillierte Anleitung des Code-Flowers-Projekts, falls ihr Interesse bekommen habt eure eigenen Grafiken zu generieren.

Stand: 15. Dezember 2014

Stand: 15. Dezember 2014

Mehrfachauswahl in Icinga Web 2

Icinga Web 2 bringt viele Interfaceverbesserungen, eine von den etwas weniger offensichtlichen ist der neue komfortablere Weg mehrere Hosts und Services gleichzeitig auszuwählen: Statt wie in der alten Weboberfläche über eine Liste von Checkboxen, funktioniert die Mehrfachauswahl jetzt über Strg und Shift wie in Desktopanwendungen.
Hier ein kleines Beispiel der praktischen Anwendung der Funktion:
1. Wir sehen auf dem Dashboard dass mehrere Hosts down und unbestätigt sind.
1-probleme-auf-dashboard
2. Mit der gedrückten Shift-Taste selektieren wir ein Intervall von 10 Hosts gleichzeitig, indem wir auf den ersten und letzten Host drücken. Durch die Auswahl öffnet sich die Detailansicht, die uns alle verfügbaren Aktionen auf den selektierten Hosts zeigt.
2-multiselection
3. In der Detailansicht können wir alle Host-Probleme bestätigen und sehen anschließend im Dashboard sofort die Auswirkungen unserer Aktion.
3-acknowledge
4-done
Neben Shift für die Auswahl von Intervallen, kann zusätzlich noch Strg verwendet werden um mehrere Objekte einzeln auszuwählen.

PHP SPL: Verkettete Listen

Eine nützliche Klasse die durch SPL ihren Einzug in PHP gefunden hat, ist die SplDoublyLinkedList, die Implementierung einer doppelt verketteten Liste.
Eine verkettete Liste ist eine dynamisch erweiterbare Datenstruktur, die beliebig viele Elemente speichern und enumerieren kann. In vielen Sprachen, in denen die Größe von Arrays bereits statisch beim Erstellen festgelegt wird, sind Listen deshalb ein wichtiger Grundbaustein um wachsende Datenstrukturen zu Implementieren. Da Arrays in PHP diese Einschränkungen nicht haben und damit generell bereits alle Möglichkeiten einer Liste bieten, gab es lange Zeit keine Implementierung in der PHP-Standardbibliothek.
Das verwenden einer SplDoubleLinkedList macht aber in vielen Bereich dennoch Sinn, da diese das Einfügen von Elementen an bestimmten Positionen einfacher und performanter macht. Wenn wir in einem normalen Array ein Element an einem bestimmten Index einfügen wollen ohne ein Element zu überschreiben, können wir array_splice verwenden.

$N = 10000;
$arr = array('foo', 'bar', 'baz');
for ($i = 0; $i < $N; $i++) {
    array_splice($arr, 1, 0, $item);
}

Wie wir feststellen ist diese Implementierung nicht sonderlich performant und das Einfügen von 10000 Elementen dauert bereits fast 10 Sekunden.

time php -f ./insert_at_array.php
real 0m10.116s
user 0m10.077s
sys 0m0.024s

Die SplDoublyLinkedList beherrscht seit Version 5.5 die Funktion SplDoublyLinkedList::add, die ein Element an eine bestimmte Position in die Liste einfügen kann.

$N = 10000;
$list = new SplDoublyLinkedList();
$list->push('foo');
$list->push('bar');
$list->push('baz');
for ($i = 0; $i < $N; $i++) {
    $list->add(1, $i);
}

Time verrät uns, dass diese Implementierung mit 47ms mehr als 200 mal schneller durchläuft als die mit regulären Arrays.

time php -f ./insert_at_list.php
real 0m0.047s
user 0m0.036s
sys 0m0.008s

Erklären lässt sich dieser Unterschied mit der internen Implementierung von Arrays in PHP. Diese sind in PHP eigentlich Hash-Tabellen, weshalb beim Aufruf von array_splice, alle nachfolgenden Elemente mit einem neuen Index versehen werden müssen. In einer verketteten Liste wird der Index eines Elements nicht gespeichert, sondern nur anhand der Position in der Kette aus Elementen definiert. Hier genügt es die Referenzen des Vorgängers und des Nachfolgers zu ändern um alle Nachfolger einen Index nach hinten zu verschieben.
 

Effizienter "bashen" mit Alias

Jeder der wie ich häufig mit dem Terminal arbeitet, erwischt sich vermutlich öfter dabei die selben Befehle unnötigerweise mehrfach einzugeben, obwohl die Shell sehr viele Mechanismen kennt um einem so etwas zu ersparen.
Neben der Möglichkeit mit den Pfeiltasten vergangene Eingaben abzurufen oder mit Tab zu vervollständigen, kann man auch einfach den Befehl alias verwenden um neue eigene Kurzbefehle zu definieren, die dann für die aktuelle Terminal-Session gültig sind. In diesem Blogpost will ich euch einige Aliasse vorstellen die mir das Leben leichter machen.

Größe aller Ordner ausgeben

Wer die Größe aller aktuellen Unterordner im Terminal herausfinden will, kann den Befehl du verwenden. Dieser gibt die Ausgabe allerdings in Bytes und unsortiert aus und wird rekursiv alle Unterordner anzeigen,  was wenig hilfreich ist. Mit ein paar Optionen kann man die Ausgabe allerdings anpassen:

alias duh='du -h --max-depth=1 | sort -h'
Freien Platz aller Festplatten anzeigen

Wie der Befehl du gibt auch df die Ausgabe in Bytes aus und lässt nützliche Informationen wie den Typ des Dateisystems weg.

alias df='df -kTh'
Nach Prozessen suchen

Mit p schnell nach bestimmten Prozessen suchen:

alias p="ps -e | grep -i "
Pakete installieren

Statt dem langen sudo apt-get install <pkg> kann man auch einfach einen kurzen Alias für den häufig verwendeten Befehl verwenden.

alias get='sudo apt-get install'
Dauerhaft speichern

Wenn die Aliase länger als die aktuelle Session halten sollen, kann man die Befehle in die ~/.bash_profile (oder unter Ubuntu die extra dafür reservierte ~/.bash_aliases) eintragen. Mit ein wenig Googeln findet man noch unzählige weitere nützliche Aliase, mit denen man sich das Leben im Terminal leichter machen kann.

Terminal-Farben für SSH-Hosts vergeben

Wer öfter mit SSH arbeitet, läuft schnell Gefahr die Übersicht über die offenen Remote-Terminals zu verlieren. Damit man nicht versehentlich Befehle auf dem falschen Host ausführt, wäre es sinnvoll die Farben automatisch zu wechseln, sobald man sich mit SSH auf einem neuen Host einloggt. Wenn man ein bisschen sucht, findet man für das Problem gleich mehrere Lösungen, die aber alle einige Nachteile haben: Oft funktionieren diese Lösungen nur für einen bestimmten Terminal-Emulator oder die Farben verschwinden nach dem ersten clear gleich wieder.
Wer eine umfassende Lösung will, kann das Programm Colorize verwenden. Colorize führt ein beliebiges Programm in einem virtuellen Terminal aus und ändert dabei die verwendeten Farben, ohne dass ein neues Terminal-Fenster geöffnet werden muss.
Zuerst compilen wir das Programm und verschieben es nach /usr/local:

./make
sudo cp ./colorize /usr/local/bin/colorize

Um die Farben für die einzelnen Hosts zu konfigurieren, wird die neue Datei ~/.ssh/host_colors erstellt. Jedem Host auf jeder Zeile kann im ersten Eintrag eine Hintergrundfarbe und im zweiten Eintrag eine Textfarbe zugewiesen werden. Bei den Farben muss eventuell ein bisschen probiert werden, da die Terminals oft nicht alle Farben unterstützen.

my.production.host 0x990000 0xffffff

Als nächstes muss in der ~/.bash_aliases noch eine Alias gesetzt werden, in dem ssh über colorize aufgerufen wird. Dabei wird die Konfiguration für den Host aus der eben erstellen host_colors geladen:

function colorssh() {
   if [ $# -gt 2 ]
     then
       # colorize only for simple ssh commands
       ssh "#@"
       return;
   fi
   host=$1;
   array=(`cat ~/.ssh/host_colors | egrep "^\s*$host\s+" | sed -e "s/^\s*//" | sed -e "s/\s\s*/ /"`)
   backg=${array[1]}
   foreg=${array[2]}
   if [ -z $backg ]
     then
       backg="0x111111";
   fi
   if [ -z $foreg ]
    then
      foreg="0xffffff";
    fi
   colorize -b $backg -f $foreg ssh "$@"
}
alias ssh=colorssh

Wenn man jetzt mit ssh den Host my.production.host öffnet, wird sich die die Farbe beim Start automatisch ändern.

An der Farbe kann man schnell erkennen, auf welchem Host sich das Terminal momentan befindet.

An der Farbe kann man schnell erkennen, auf welchem Host sich das Terminal momentan befindet.

Ordner im Netzwerk mit Csync synchronisieren

Wer einen Laptop zusammen mit einem Desktop oder Fileserver besitzt, wird schnell das Problem bekommen dass alle Dokumente und Dateien über mehrere Computer verteilt liegen und man unterwegs mit dem Laptop nie die passenden dabei hat. Die bekannteste Lösung für das Problem ist natürlich ein Cloud-Storage wie Dropbox oder OwnCloud. Wenn die Datenmengen sehr groß sind und man keine eigene Installation von OwnCloud im Heimnetzwerk verwalten will, ist so eine Lösung allerdings nicht wirklich geeignet.

Csync ist ein leichtgewichtiges Terminalprogramm mit dem Dateien und Ordner über das Netzwerk synchronisiert werden können. Die Namensverwandtschaft mit dem bekannten Rsync ist dabei kein Zufall, da Csync sehr ähnlich funktioniert. Der große Unterschied zu Rsync ist jedoch, dass Csync zwei Ordner bidirektional synchronisiert, was bedeutet dass Änderungen in beiden Ordnern erkannt werden um diese auf einen gemeinsamen Stand zu bringen. Wer das Programm installieren möchte findet hier eine Anleitung um Csync aus den Sourcen zu bauen, oder hier ein fertiges .DEB-Paket für 64-Bit Ubuntu/Mint.

Csync kann nach der Installation aus dem Terminal aufgerufen werden:

csync [SOURCE] [DESTINATION]

Source und Destionation können entweder lokale Ordner, oder Pfade auf Geräten im Netzwerk sein. Um auch entfernte Rechner zugreifen zu können muss ein SMB-Account mit Lese- und Schreibzugriff vorhanden sein.

csync ~/Music smb://matthias:passwort@MeinFileserver/Matthias/Music

Dieser Befehl würde alle Dateien in “Music” mit dem Fileserver synchronisieren. Dabei ist es egal ob Dateien auf dem Fileserver oder zuerst auf dem Laptop hinzugefügt oder gelöscht werden, da Csync anhand des Änderungsdatums und der gespeicherten Zustandsdaten erkennt welche Änderung im Netzwerk synchronisiert werden muss.

Wenn man möchte dass die Synchronisierung regelmäßig durchgeführt wird, kann man zum Beispiel CRON verwenden um den Befehl in gewissen Zeitabständen zu wiederholen lassen. Dieser Eintrag im Crontab würde Csync einmal pro Stunde aufrufen:

 0  * * * * csync /home/matthias/Music smb://matthias:passwort@MeinFileserver/Matthias/Music