I have a number of launch agents I've written over the years to automate some simple tasks, like rsyncing my music and photos from my laptop to my NAS. Recently I've noticed that they have stopped running daily like they used to. Instead, they're only running when I log in. Here's a sample launchagent:
<?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.mwheinz.backup_photos</string>
<key>Program</key>
<string>/Users/michaelheinz/bin/backup_photos</string>
<key>StartInterval</key>
<integer>86400</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
When I run them with "debug" it says they are configured to run "at launch":
~ » sudo launchctl debug gui/501/com.mwheinz.backup_books
Password:
Service configured for next launch.
Any suggestions? One thing I've noticed is that launchd now insists I refer to my agents as "gui/501/<label>" instead of just "<label>".
Okay - I figured it out. The problem for me was that the syntax for the plists changed at some point. This syntax:
Program
/Users/michaelheinz/bin/backup_books
StartInterval
became this syntax:
ProgramArguments
/Users/michaelheinz/bin/backup_books
StartInterval
I changed all my plists and they started working again.
Related
I have a launch daemon plist that runs a python script. The problem is that it is unable to run the script because it does not have access to python.
I am trying to make a launch daemon to change mac address (https://github.com/feross/SpoofMAC)
Here is the plist file in /Library/LaunchDaemons:
<?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>MacSpoof</string>
<key>ProgramArguments</key>
<array>
<string>/Users/username/.asdf/shims/spoof-mac.py</string>
<string>randomize</string>
<string>en0</string>
</array>
<key>StandardOutPath</key>
<string>/Users/username/Projects/MAC/out.log</string>
<key>StandardErrorPath</key>
<string>/Users/username/Projects/MAC/err.log</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
The Error Log reads:
No version is set for command spoof-mac.py
Consider adding one of the following versions in your config file at
python 3.11.1
My tool_version does include Python, how can I make this work?
Okay, I kinda got it working. I moved the plist file from /Library/LaunchDaemons to /Library/LaunchAgents and it works because LaunchAgents run after the user is logged in. It's not exactly what I wanted, but it works.
I'm trying to get a "daemon" (really just a script, more than a background process) to activate when a file (specifically, /dev/console) changes owner (i.e., when another user takes control of the console) on MacOS Mojave.
I'm trying to do this by running launchd and having it watch that file for changes. I tried doing this with WatchPaths, as in the script below, but apparently that only notices "creating, removing and writing to this file", not chown. Script is below, along with more background story. Any ideas on how to do this?
<?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>LoginScripts.blockyoutube.sh</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Shared/blockyoutube.sh</string>
</array>
<key>WatchPaths</key>
<array>
<string>/dev/console</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/blockyoutube.log</string>
<key>StandardErrorPath</key>
<string>/var/log/blockyoutube.log</string>
</dict>
</plist>
Backstory
What I'm really trying to do is block my kids' accounts from YouTube ... but not my wife's account on the same computer. In theory System Preferences->Parental Controls should do this fine — which it does ... until someone launches Chrome and it backchannels the DNS lookup to 8.8.8.8.
The only way I've figured out to work around this is to not let the OS DNS query fail, so Chrome doesn't attempt to do that, so I'm updating /etc/hosts to point to localhost and flushing DNS whenever the console owner changes. Other solutions to this backstory are also welcome, but it does seem that there should be a way to make launchd watch for change in owner of a file.
I'd like to run an app I created via Automator every 5 minutes, so I placed the following com.user.wilson.plist file in this folder:
/Library/LaunchAgents
<?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.user.wilson</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
<string>-a</string>
<string>/Users/paul/Documents/Wilson/Script/mt-wilson-background_app</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
</dict>
</plist>
Then, I loaded it using the following command in the terminal:
launchctl load Library/LaunchAgents/com.user.wilson.plist
but for some reason, the app never runs.
I can, however, successfully run the app using this command:
/usr/bin/open -a /Users/paul/Documents/Wilson/Script/mt-wilson-background_app
Any ideas why the .plist file won't do what I'm expecting it to?
In order to see what's going wrong, you can add a log file in your plist like this:
<?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.user.wilson</string>
<key>StandardErrorPath</key>
<string>/Users/paul/Documents/Wilson/Script/err.log</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
<string>-a</string>
<string>/Users/paul/Documents/Wilson/Script/mt-wilson-background_app</string>
</array>
<key>StartInterval</key>
<integer>300</integer>
</dict>
</plist>
Note: For the modifications to take effect, unload and load again:
launchctl unload Library/LaunchAgents/com.user.wilson.plist
launchctl load Library/LaunchAgents/com.user.wilson.plist
Typically, if the err.log says it can't find your app, it means it's a permission issue.
I would suggest you try to move your app from /Users/paul/Documents/Wilson/Script/mt-wilson-background_app to /Users/paul/Documents/mt-wilson-background_app
Then update your plist accordingly, unload an reload your plist, is it working better now?
I ran into nearly the exact same problem. I finally (FINALLY!!!) found a cure that worked for me.
Originally, the broken version of the .plist launch agent that wouldn't run no matter what I tried was in /Library/LaunchAgents. Moving the agent to /Users/[me]/LaunchAgents eliminated the "Application Not Running" error.
It seems counterintuitive since the root agent should be able to run everything from any location, but I can only guess that AppleScript's check to see if an app is running or not is user account-dependent somehow. I'm betting there's something you can add to the AppleScript to actually fix this the "right" way, but this works well enough for me, so I'm taking the win.
First time here and already in trouble... so here's the deal :
- Mac OS X 10.8.4
- SCCM 2012
- XServe 10.7 + DeployStudio 1.6.2
I deploy my iMacs using DeployStudio. As a part of the deployment process, the Macs are binded to AD & OD. I need also to install the Microsoft SCCM 2012 client. In order for the iMacs to properly communicate with SCCM and being furtherly managed, I need them to enroll a certificate at first boot. My colleague and myself tried a couple of different methods, no luck yet.
So what we currently have in mind is to copy a plist in the LaunchDemons folder and the enroll script in another location to be run by launchd. Problem is : doesn't work... and no logs whatsoever ! :confused:
Here's the plist :
<?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>com.sccm.enrollcert</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/enroll</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Very simple as you can see...
And here's the enroll.sh script :
#!/usr/bin/expect
spawn /usr/bin/CMEnroll -s SCCM.DOMAIN.local -ignorecertchainvalidation -u "DOMAIN\ACCOUNT"
expect "Please enter your password."
send "passwd\n"
sleep 50
So as you can see it pretty simple... but for some funny reason it doesn't work at all.
Is there something we're missing by using "expect"/"spawn" in a launchd script like that ?
Thanks in advance
it looks like it loads but has a status of 1 when using launchctl list
and using launchctl start ... it says No such Process...
i have it saved in /Users/IMG/Library/LaunchAgents.
The sh script runs fine.
the logging doesn't show anything - no file created..
I am very new to plist so please forgive ignorance.
<?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.IMG.shed</string>
<key>ProgramArguments</key>
<array>
<string>/Users/IMG/2012/Dropbox/Dev_2012/Java/sh_IMG.sh</string>
</array>
<key>StandardOutPath</key>
<string>myjob.log</string>
<key>StandardErrorPath</key>
<string>myjob.log</string>
<key>Debug</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>StartInterval</key>
<integer>60</integer>
</dict>
</plist>
The first thing I thought was the process does not have permission to create the standard output log file (although I imagine the default value for working directory for a personal agent would be the user's home directory). There is an optional property key for WorkingDirectory - perhaps try setting that to see if anything changes.
Reference: Launchd.plist man page
In XCode 4.5.2, under the Product menu, you need to pick Edit Scheme. You will see the manage schemes box appear with several schemes. One of these is called Run <ProjectName>. Click the checkbox next to Working Directory Use custom working directory and point that to the path where your plist is at.
This elaborates on the answer given by unhillbilly. So thanks unhillbilly for steering me towards the Working Directory.