Bash-Skript bei der Anmeldung ausführen, die im Basisordner gespeichert ist?

19

Wenn ich versuche, eine LaunchAgent-Liste von zu laden, launchctlkann ich nicht herausfinden, wie ein Skript im Ausgangsverzeichnis ausgeführt wird .

Mein Code ist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProgramArguments</key>
    <array>
        <string>bash</string>
        <string>~/script.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>com.tyilo.test</string>
</dict>
</plist>

Ich habe sowohl mit als auch ohne Bash versucht und auch ~mit ersetzt $HOME. Ich habe es auch versucht, bash -cohne dass es funktioniert.

Der Fehlercode lautet:

`com.tyilo.test: bash: ~/script.sh: No such file or directory`
Tyilo
quelle
Versuchen Sie den vollständigen Pfad zB /Users/name/script.sh setzen (Auch ich würde das Skript ausführbar machen und mit ersten Zeile # ! / Bin / bash und führen Sie es direkt!)
user151019
Ich kann den vollständigen Pfad nicht verwenden, da er auf mehreren Konten und Computern verwendet werden soll.
Tyilo
1
Wenn es für meine mehreren Konten verwendet werden soll, sollten Sie es in / usr / local / bin / ablegen, anstatt mehrere Kopien davon in $ HOME jedes Benutzers zu erstellen. Es wäre hilfreich zu wissen, was Sie mit diesem Skript erreichen möchten. Es klingt wie ein Job für einen LoginHook, IMO.
TJ Luoma,

Antworten:

14

EnableGlobbingAktiviert die Tilde- und Wildcard-Erweiterung für ProgramArguments:

<key>EnableGlobbing</key>
<true/>
<key>ProgramArguments</key>
<array>
    <string>say</string>
    <string>~/*</string>
</array>

Dies hat keine Auswirkung auf Programoder WatchPaths, jedoch funktioniert die Tilde-Erweiterung WatchPathsstandardmäßig.

Lri
quelle
Das ist viel besser. Gibt es eine Stelle, an der Sie die Dokumentation für die Schlüssel in einer LaunchAgent-Liste anzeigen können?
Tyilo
Mann launchd.plist. Oder sehen Sie diesen Blog-Beitrag oder meine Website .
Lri
1
Das hat mir auch geholfen. Versucht in den folgenden Mac OS X-Versionen: 10.7, 10.8 und 10.9.
Dj S
6
Bitte beachten Sie: Diese Funktion wurde in Yosemite ( Mac OS X 10.10+) entfernt.
Alex Gray
Sieht so aus, als wäre es auch nicht in 10.9.5
ocodo
18

EnableGlobbing funktioniert unter OS X Yosemite 10.10 nicht . Es wurde veraltet ( ref ).

Sie können in Protokollen sehen The EnableGlobbing key is no longer respected. Please remove it.(von /var/log/system.log)

Das Problem ist, dass launchdcwd (aktuelles Arbeitsverzeichnis) ist /, so dass Sie es nicht verwenden können, ./wie einige Leute sagten.

Um ein Skript von zu Hause aus auszuführen, verwenden Sie einfach (bash|zsh|sh) -c. Möglichkeit. Auf diese Weise können Sie die Tilde ~oder die $HOMEVariable verwenden.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>org.your.stuff</string>
    <key>ProgramArguments</key>
    <array>
      <!-- here is the important thing -->
      <string>zsh</string>
      <string>-c</string>
      <string>~/you/script/in/your/home</string>
    </array>

    <!-- code below is just for the example -->
    <!-- Keep running... -->
    <key>KeepAlive</key>
    <true />
    <!-- ...every day. In sec, 60*60*24 = every day -->
    <key>ThrottleInterval</key>
    <integer>86400</integer>
  </dict>
</plist>
MoOx
quelle
2
Ich glaube nicht, dass Sie mit Tilde umgehen können sh. Wenn Bash as beteiligt ist sh, wird es im POSIX-Kompatibilitätsmodus ausgeführt, der viele Bash-Erweiterungen deaktiviert.
Tripleee
~/verschlingt also nicht unterstützt. Sie können ./stattdessen verwenden, solange der Dämon in der Heimbibliothek des Benutzers gespeichert ist. ( ~/Library/LaunchAgents)
Bruno
9

Das zuverlässigste, was ich dabei gefunden habe, war die Verwendung von shund der HOMEUmgebungsvariablen:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ProgramArguments</key>
    <array>
        <string>sh</string>
        <string>-c</string>
        <string>"$HOME/script.sh"</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Label</key>
    <string>com.tyilo.test</string>
</dict>
</plist>

Hinweis: Die Anführungszeichen sind erforderlich.

Tyilo
quelle
2

Es wäre hilfreich zu wissen, warum das Skript aus dem Ausgangsverzeichnis des Benutzers ausgeführt werden muss. Wenn Sie den Kurznamen des Benutzers für das Skript benötigen, können Sie ihn abrufen, indem Sie ihn einer Variablen wie in zuweisen

user=`whoami`

Dann $userim Skript verwenden.

Ich würde das Skript wirklich an einem anderen Ort als in einem Home-Verzeichnis ablegen, auf das andere Benutzer auf demselben Computer zugreifen können. Sie können das freigegebene Verzeichnis verwenden oder das Skript in / Library / Scripts / ablegen.

Sie müssen den vollständigen Pfad für die launchd-Liste verwenden. Außerdem müssen Sie in Ihrer launchd plist keine Angaben machen, <string>bash</string>da Sie den shebang im Skript haben sollten und er ausführbar sein sollte.

afragen
quelle
Das Angeben bashals tatsächlich auszuführenden Befehl ist ein guter Fallback ohne wirklichen Schaden. Wenn er nicht über den Shebang verfügt oder vergisst, das Skript ausführbar zu machen (o = rwx), ruft bash das Skript trotzdem auf / führt es aus.
Jason Salaz
1
Für den Benutzernamen sollte bereits eine Variable vorhanden sein, z. B. $ USER oder $ LOGNAME. Der übliche Speicherort für gemeinsam genutzte Unix-Skripte wäre / usr / local / bin / (nicht, dass Sie sie an anderer Stelle ablegen könnten, aber / usr / local / bin / wird sich höchstwahrscheinlich bereits in Ihrem $ PATH befinden).
TJ Luoma,
Whoami ist nur eine andere Methode, um auf die gleichen Informationen wie $ USER oder $ LOGNAME zuzugreifen. Ich schlug die oben genannten Orte vor, da ich nichts von dem Fragesteller annehmen wollte. Außerdem muss das Skript in der Lage sein, über die CLI ausgeführt zu werden, bevor versucht wird, die launchd plist zum Laufen zu bringen.
afragen
1

Ist es ausführbar?

chmod 700 ~/script.sh

im Terminal. Außerdem würde ich nicht $ HOME oder ~ verwenden, sondern den tatsächlichen Pfad zur Datei.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.tyilo.test</string>
    <key>ProgramArguments</key>
    <array>
        <string>/path/to/script.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>
TJ Luoma
quelle
Was ist der Grund für die Ablehnung?
TJ Luoma
1

Wenn Ihr Skript ein Benutzeragent ist (und sich daher in der Bibliothek des Basisordners befindet), launchdist das aktuelle Arbeitsverzeichnis der Basisordner. UNIX verweist auf das Basisverzeichnis mit einem Punkt im Pfad.

Verwenden Sie also im Grunde genommen ./script.shstatt ~/script.sh. ;-)

Constantino Tsarouhas
quelle
3
Nein, das Arbeitsverzeichnis von launchd ist eigentlich /nicht '~'.
Tyilo
@ Tyilo Ich bin nicht sicher, was du meinst. Wenn Sie meinen, "das Arbeitsverzeichnis von launchd ist in jedem Fall das Stammverzeichnis - auch im Benutzermodus", geben Sie eine Referenz an. Wenn Sie meinen "launchd verwendet einen Schrägstrich anstelle einer Tilde", lesen Sie meinen Beitrag noch einmal. Übrigens habe ich in launchd mehrere Skripte geplant, die dem von mir beschriebenen Verhalten folgen. ;-)
Constantino Tsarouhas
1
@RandyMarch Ich machte einen Startmittel in ~/Library/LaunchAgentsmit den Argumenten: sh, -c, echo $HOME > /Users/Tyilo/launchd_home.txt. Wann lief die Datei /Users/Tyilo/launchd_home.txtenthalten /, nicht /Users/Tyilo.
Tyilo