Ausführen eines Befehls, wenn der Mac mit launchctl/plist hochfährt

Ich muss den nohup nice synergys -f --config ~/bin/conf/synergy.conf &Befehl ausführen, wenn der Computer hochfährt.

Wie in diesem Beitrag geschrieben , habe ich mir den folgenden Plist-Code ausgedacht.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>synergy</string>
    <key>ProgramArguments</key>
    <array>
        <string>nohup nice /usr/bin/synergys -f --config /Users/USER/bin/conf/synergy.conf &</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>LaunchOnlyOnce</key>
    <true/>
</dict>
</plist>

Und diesen Befehl ausgeführt.

launchctl load ./synergy.plist 

Allerdings bekam ich diese Fehlermeldung.

launchctl: no plist was returned for: ./synergy.plist
launchctl: no plist was returned for: ./synergy.plist
nothing found to load

Was stimmt nicht mit meiner Plist? Oder ist mein launchctrl-Befehl in den Optionen falsch?

Antworten (1)

Das unmittelbare Problem ist, dass Ihre .plist-Datei nicht korrekt formatiert ist – der Inhalt von <string>...</string>sollte mit HTML-Entitäten codiert werden, dh &muss als codiert werden &amp;(Hinweis: Sie können das Format von .plist-Dateien mit überprüfen plutil -lint filename.plist). Aber es gibt noch einige andere Änderungen, die vorgenommen werden müssen ...

Das Starten von Programmen mit launchd ist ziemlich anders als das Starten von Programmen aus einer Shell. Der größte Unterschied besteht darin, dass Sie möchten, dass das Programm von der Shell in den Hintergrund geht und unabhängig von der Shell läuft, also packen Sie es in nohup ... &. Bei launchd ist es eigentlich am besten, wenn das Programm im "Vordergrund" bleibt, damit launchd es im Auge behalten kann.

Außerdem werden die Elemente von ProgramArguments nicht von einer Shell geparst, daher funktioniert das Auflisten des Befehls und seiner Argumente mit Leerzeichen nicht – machen Sie jedes Argument zu einem separaten Element des Arrays.

Hier ist mein Versuch einer Synergie-.plist. Ich habe dies nicht getestet, daher muss es möglicherweise ein wenig angepasst werden, damit es ordnungsgemäß funktioniert (siehe Anmerkungen unten):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>local.synergy</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/synergys</string>
        <string>-f</string>
        <string>--config</string>
        <string>/Users/USER/bin/conf/synergy.conf</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Nice</key>
    <integer>10</integer>
    <key>KeepAlive</key>
    <false/>
    <key>AbandonProcessGroup</key>
    <true/>
</dict>
</plist>

Die letzten beiden Schlüssel oben befassen sich damit, wie launchd reagieren soll, wenn/wenn das synergys-Programm beendet wird. Standardmäßig beendet es alle überlebenden Unterprozesse und startet eine neue Instanz; Diese beiden Tasten unterdrücken beide Teile, was Sie wollen oder auch nicht. Eine Sache, die dies nicht tut, nohupist die Umleitung von stdin und stdout zu nohup.out (falls das Terminal verschwindet); Stattdessen protokolliert IIRC launchd Dinge, die an sie gesendet werden. Wenn synergys die Gewohnheit hat, Ausgaben zu senden, möchten Sie vielleicht so etwas zur .plist hinzufügen:

    <key>StandardOutPath</key>
    <string>/dev/null</string>
    <key>StandardErrorPath</key>
    <string>/dev/null</string>

Außerdem sollten Sie, wie Mankoff sagte, dies in ~/Library/LaunchAgents ablegen, damit es bei jeder Anmeldung automatisch geladen local.wird an die Reverse-DNS-Namenskonvention.

OMG, danke dafür: plutil -lint filename.plist
Toller Tipp für den Plutil, sehr praktisch
Wozu dient der Schlüssel Niceund die Ganzzahl 10?
Gibt es auch einen Grund, warum Sie <key>Program</key><string>/usr/bin/synergys</string>den Rest der Argumente nicht als übergeben <key>ProgramArguments</key><array><string>Argument_1</string><string>Argument_2</string></array>?
@hobbes3: Der NiceWert führt das Programm mit niedrigerer Priorität aus, was dem netten Befehl im Original entspricht. Der Grund, warum ich es nicht verwendet habe, <key>Program</key>ist Redundanz (und Faulheit): Sie müssten /usr/bin/synergysals Program und auch als erstes Element von auflisten ProgramArguments.