I am trying to execute an Apple Script from my launchd daemon. My script has just one line and it is given below.
say "Message From Daemon!"
This always fails and throws this error message "File some object wasn't found".
Any idea why this is happening? The same script works properly if I run from xcode (not launching it via launchd) and from any other app that runs in user context.
Playing sound using NSSound rely on the window server and daemon is not allowed to connect to the window server.
I am assuming same issue with say command. ( This tool uses the Speech Synthesis manager to convert input text to audible speech and either play it through the sound output device chosen in System
Preferences or save it to an AIFF file.)
I'm guessing you're running into the same problem I had originally when I tried the same kind of thing. The path in your .plist file needs to point deeper into the applescript application. Below is an example of the .plist file.
<?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.namespace.script_name</string>
<key>Program</key>
<string>/Applications/script_name.app/Contents/MacOS/applet</string>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>7200</integer>
</dict>
</plist>
Related
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.
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 am trying to start ngrok automatically when my mac mini starts up. I thought maybe OSX had something like the init-folder on ubuntu where you place scripts you want to start automatically, but i haven't found anything like it.
Are there no way to just run commands on startup on OSX?
You can create a LaunchDaemon to run ngrok on startup (or a LaunchAgent if you want to start ngrok after a user logs in). See the apple docs.
A LaunchDaemon is a plist that resides in /Library/LaunchDaemons/. For example, my LaunchDaemon (/Library/LaunchDaemons/com.ngrok.onstartup.plist) looks something 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.ngrok.onstartup</string>
<key>Program</key>
<string>/path/to/ngrokd</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
The choice of the Label is up to you as long as it uniquely identifies your daemon. In this example my LaunchDaemon is called com.ngrok.onstartup.
ngrokd is a bash script looking like this:
#!/bin/sh
/usr/local/bin/ngrok -log=/path/to/ngrok.log -config=/path/to/ngrok.yml start ssh
You can check that launchd started your daemon by typing:
sudo launchctl list com.ngrok.onstartup
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
I'm trying to create a plist for the LaunchAgents folder that will run perpetually and call a shell script every 30 seconds. It started with a template that I got here and that I tried to tailor to fit my needs, but it's still not working. Any help?
<?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.Intel_Watchdog</string>
<key>ProgramArguments</key>
<array>
<string>/Library/A_Intel_WATCHDOG/A_WatchDog.sh</string>
</array>
<key>StandardErrorPath</key>
<string>/dev/null</string>
<key>StandardOutPath</key>
<string>/dev/null</string>
<key>StartInterval</key>
<integer>30</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
Thanks so much!
I dropped this in my LaunchDaemons directory, and it worked fine. So, here're some things to check:
Is the .plist getting loaded? Note that the contents of the LaunchAgents folders are loaded at login, so you either need to log out and back in, or manually load it with launchctl load ~/Library/LaunchAgents/com.Intel_Watchdog.plist (or whatever/wherever the file is). You can check its status with launchctl list.
Is /Library/A_Intel_WATCHDOG/A_WatchDog.sh executable? Check the system log (/var/log/system.log) to see if launchd is having trouble launching it.
Is the script running into trouble before it does its job? Try adding date >>/tmp/watchdog.log to it, right after the shebang, and see if anything appears in /tmp/watchdog.log. If it does, try changing the StandardErrorPath and StandardOutPath to an actual file so you can see what's going on as the script runs. Note that you'll have to unload and reload the .plist to get the change to take effect (logging out and back in would do it).
Finally, although it shouldn't cause trouble, your label doesn't follow the standard convention (unless you actually own the domain Intel_Watchdog.com). If this is for local-only use, name it something like local.Intel_Watchdog instead. If you're going to publish this item, you should base the label on a domain you own (in reverse order, with ".Intel_Watchdog" added to the end) -- see Wikipedia's entry on the reverse domain name system.