Von allen guten und bösen Geistern verlassen

Skripte automatisiert unter Mac OS X ausführen

Skripte unter Mac OS X automatisieren klingt verlockend. Allerdings ist der Weg dorthin mit einer ganzen Reihe von Steinen gepflastert.

To cron or not to cron?

Mit meinem Skript zur Synchronisierung eines lokalen Vaults in Obsidian mit der iCloud bin ich ziemlich zufrieden. Auf diese Weise habe ich wichtige Information auch auf dem iPhone und iPad zur Verfügung. Im Blogartikel Anfang des Monats deutete ich bereits an, dass mir eine Automatisierung der Synchronisierung gefallen würde. Der Weg dort hin war alles andere als einfach, aber jetzt, wo ich mir keine Gedanken mehr um den Abgleich machen muss, ist es eine ziemliche Erleichterung auch im Workflow. Das Wissen zur Realisierung teile ich gerne.

Meine erste Überlegung zufolge müsste die Umsetzung recht einfach sein. Mit dem Cron-Daemon habe ich bereits bei Webserver Erfahrung — gehört schließlich zu meinem Job. Allerdings ist es so, dass Apple seit einiger Zeit cron nicht mehr unterstützt und stattdessen auch bei systemeigenen Prozessen auf launchd setzt. Die Konfiguration unterscheidet sich dabei erheblich von cron & crontab.

Voraussetzung für die Automatisierung eines Skriptes ist eine Eigenschaftsliste (Property List), eine sogenannte plist. Dabei ist eine plist-Datei im Prinzip eine XML-Datei, die eine Reihe von Angaben erfordert, damit launchd damit etwas anfangen kann. In der Datei wird unter anderem angegeben, was und vor allem wann es ausgeführt werden soll.

Mein erster Versuch mit einer auf die Schnelle zusammengesuchten Konfiguration und dem Aufruf sudo launchctl load -w de.tboley.obsidian_sync.plistging ziemlich daneben und sorgte für Frust.

Endlich Skripte automatisieren

Die Suche nach den Fehlern — es gibt an dieser Stelle eine ganze Reihe von Ursachen — gestaltet sich ziemlich mühsam. Es fängt bei Dateirechten an, die weitreichender gesetzt werden müssen, wenn das Skript im Hintergrund vom System und nicht manuell vom aktuellen Benutzer ausgeführt werden soll. Dazu kommen möglicherweise Sonderzeichen in der Pfadangabe und auch der Umstand, dass man für den Aufruf von unison am besten ein Batch-Skript anlegt. Wenn das Bash-Skript beim manuellen Aufruf über die Shell funktioniert, heißt das noch lange nicht, dass es auch mit launchd so sein wird.

Nach einer ganzen Reihe von Fehlschlägen und alten Tutorials, die nicht weiterhalfen, gab ich den Versuch auf, manuell eine gültige plist-Datei zu erstellen. Ich lud mir die Demoversion von LaunchControl herunter und erwarb dann auch kurzerhand eine Lizenz, um selber einen Service damit konfigurieren zu können.

Dabei ist LaunchControl nicht nur eine große Hilfe beim Erstellen der plist, sondern insbesondere auch bei der Fehlersuche. Stück für Stück konnte ich mich so voran arbeiten.

Bash-Skripte sollen auf keinen Fall im Dokumentenordner des Benutzers gespeichert werden, sondern am besten in einem Ordner direkt unter dem Benutzerordner. Am besten ändert man die Zugriffsrechte für diesen Ordner mit chmod 755, sodass launchd darauf zugreifen kann.

Aufbau der Bash-Datei

Ausgangspunkt bei meinen Bemühungen zur Automatisierung ist eine Bash-Datei, die den Aufruf von unsion enthält:

#!/bin/bash

set -x
/usr/local/Cellar/unison/2.53.3/bin/unison /Users/tboley/SynologyDrive/Notizen/Sync/  '/Users/tboley/Library/Mobile Documents/iCloud~md~obsidian/Documents/mobileVault/' -silent -terse

Entscheidend ist hier, dass der vollständige Pfad zu unsion angeben werden muss — als das Verzeichnis, wo Hombrew die Anwendung installiert hat. Nutzt man die Bash-Datei selber nur im Terminal, ist das nicht erforderlich. Für launchd aber auf jeden Fall.

Warum ich set -xals Anweisung im Skript habe, kann ich an dieser Stelle leider nicht mehr nachvollziehen. Vermutlich hing das mit der Ausgabe der Fehler in LaunchControl zusammen.

Wichtig (und das weiß ich noch) sind bei der zweiten Pfadangabe die Anführungszeichen, da der Pfad Sonderzeichen enthält. Auch das ist bei einem direkten Aufruf der Bash-Datei nicht erforderlich.

Sieg nach Punkte

Zusammengefasst hat es mich ziemlich viel Zeit gekostet, einen Befehl, der sich manuell über Kurzbefehle anstoßen ließ, mit launchd zu automatisieren. Allerdings läuft jetzt bei mir ein Hintergrundprozess, der sich selbständig darum kümmert, meinen Vault in der iCloud mit einem Teil meines Vaults auf dem Desktop zu synchronisieren.

Wenn die Dateien mal nicht synchronisiert wurden, liegt das zu 99,5 Prozent nicht an meinen Einstellungen, sondern an iCloud. Die lässt sich nämlich mitunter mal etwas Zeit, bis Daten von iOS-Geräten auf dem Desktop auftauchen (oder umgekehrt). Was nicht in meinem lokalen iCloud Ordner ist, kann ich auch nicht synchronisieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.

DSGVO Cookie Consent mit Real Cookie Banner