I have tried to follow this question so that at login, the currently configured screensaver becomes the desktop background. Therefore, I have created the following script:

# login.sh
/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background &

I have then created a launch service as ~/Library/LaunchAgents/my_login_items.plist with the content

<?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">

And then run launchctl load ~/Library/LaunchAgents/my_login_items.plist. Nothing happens, however.

  • Does login.sh work when you run it from the command line? (I'm assuming it does, but wanted to check). When you launchctl load does it work? (Again, I'm assuming it doesn't, but need to check). Finally, and this strays into "answer" territory, could you try adding StandardOutPath and StandardErrorPath to your plist so the agent logs whats happening? (<key>StandardOutPath</key> <string>/tmp/test.stdout</string> <key>StandardErrorPath</key> <string>/tmp/test.stderr</string>)
    – John N
    Commented Jan 17, 2017 at 9:59
  • @JohnN Both of your assumptions are correct. I added the path keys, but both log files stay empty.
    – oarfish
    Commented Jan 17, 2017 at 10:05
  • Ah, that's disappointing. I'll have a play around and see if I can replicate this.
    – John N
    Commented Jan 17, 2017 at 10:08

1 Answer 1


This is a deeply unsatisfying answer, but I got it to work by running /System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background & in a subshell. I changed login.sh to...

shortname=$(basename "${longname}")
echo "$(date -u "+%Y-%m-%d %H:%M:%S") ${shortname} (${longname}) running..."
output=$(/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine -background)    # <- COMMAND GOES HERE            
echo "$(date -u "+%Y-%m-%d %H:%M:%S") ${shortname} ended."

...and that works (my usual static desktop changes to my default screensaver). I use this idiom for other launchd tasks, running the tasks in a subshell so I can easily test whether the operation succeeded and log $output. I don't understand why this works while your original doesn't, but at least it does work.

Note that I removed the & from the end of your command - I'm not convinced this is necessary with launchd, and it was preventing my wrapper script from logging that it had ended (though the & wasn't the cause of the original problem).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .