0

For some reason, Dropbox terminates (crashes or quits) after being online a few days, with no explanation.

I therefore started to research a way for AppleScript to automatically restart the application when it terminates.

That led me to this script:

repeat
    delay 120 #Run every two minutes
    tell application "System Events"
        if name of every process does not contain "Dropbox" then tell application "Dropbox" to launch
    end tell
    delay 5
end repeat

I also want the script to run in the background, so I implemented my own variant of this Ask Different solution for launchctl.

In ~/Library/LaunchAgents/, I create a file named dropbox-keep-alive.plist with this content:

<?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>dropbox-keep-alive.job</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/osascript</string>
        <string>/Users/xxx/Library/Mobile\ Documents/com\~apple\~ScriptEditor2/Documents/dropbox-keep-alive.scpt</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

The path to the AppleScript is given in the <array> above, and a .job label for launchutil is assigned under <key>.

I then load the .plist:

launchctl load -w ~/Library/LaunchAgents/dropbox-keep-alive.plist

And then start it:

launchctl start dropbox-keep-alive.job

For testing, I quit Dropbox and then wait 2+ minutes, but nothing happens.

If I try launchctl load -w again, I get the message that it's already loaded. launchctl start gives no response message.

I know that the AppleScript works because it's functional when running it with osascript directly. But somewhere in the .plist – or my management of launchctl – there is something that doesn't work.

I have tried to launchctl unload -w the script and redo the process. Any ideas?

Community
  • 1
  • 1
P A N
  • 5,642
  • 15
  • 52
  • 103
  • 1
    Actually you don't need a script. `launchctl.plist` has a `KeepAlive` key – vadian Mar 09 '16 at 10:31
  • @vadian Thanks for your suggestion! So I would only need to include `KeepAlive` and some sort of identifier for the Dropbox app (not sure how)? Feel free to leave an answer if you know the solution. – P A N Mar 09 '16 at 14:34
  • You have to specify the full path to the Dropbox executable (not the application bundle) in the `ProgramArguments` array. – vadian Mar 09 '16 at 14:37
  • @vadian Thanks, figured it out. Much better than using a script! – P A N Mar 09 '16 at 14:44

2 Answers2

2

launchd doesn't do shell-style parsing on strings, so the escapes you have in the path to the script will be interpreted as part of the actual filename... and it will not be found. It should look more like this:

<key>ProgramArguments</key>
<array>
    <string>/usr/bin/osascript</string>
    <string>/Users/xxx/Library/Mobile Documents/com~apple~ScriptEditor2/Documents/dropbox-keep-alive.scpt</string>
</array>

I'm not sure this is the only problem, but it certainly is a problem. If further debugging is needed, try capturing the error output from osascript by adding something like:

<key>StandardErrorPath</key>
<string>/Users/xxx/Library/Logs/dropbox-keep-alive.err</string>
Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
1

The script file that you're asking launchd to execute is located in your user's /Library folder.

Launchd does not have access to that location. Move it to a folder such as /usr/local/sbin

TheDarkKnight
  • 27,181
  • 6
  • 55
  • 85
  • This is incorrect; launchd has normal access to the user's Library folder. – Gordon Davisson Mar 09 '16 at 16:14
  • I seriously hope not, permissions for that folder are set as *drwx------@* and there's no additional ACL. If there's a special exception for launchd to bypass POSIX permissions, then that's a security exploit waiting to happen. – TheDarkKnight Mar 09 '16 at 17:12
  • In 10.10 and 10.11, launchd runs as root and hence bypasses POSIX permissions. But that's actually irrelevant here, since it's just running `osascript` as the logged-in user and passing it "/Users/xxx/Library/..." *as a string*; `osascript` actually opens the file and since it's running as the user, it has "rwx" access to the user's Library folder. – Gordon Davisson Mar 09 '16 at 18:43
  • BTW, 10.9 and older versions of OS X ran separate instances of launchd for launch daemons (which run as root) and launch agents (which run as the logged-in user). The agent/user instances of launchd ran as the user they were managing agents for, so they'd also have access to ~/Library for that user. – Gordon Davisson Mar 09 '16 at 18:44
  • @GordonDavisson *since it's just running osascript as the logged-in user...* - Good point and thanks for the discussion. I failed to notice the script being just a parameter to the call to osascript, rather than being called directly. – TheDarkKnight Mar 10 '16 at 10:15