Run osascript (AppleScript) from launchd / launctl - macos

I am trying to run a very simple AppleScript periodically using a launchd agent but it won't do anything aside from writing the AppleScript contents to stdout.
My launchd Agent at ~/Library/LaunchAgents/com.nn.test.plist:
<?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.nn.test</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/osascript</string>
<string>-e</string>
<string>"display dialog \"Hi\""</string>
</array>
<key>RunAtLoad</key>
<false/>
<key>Debug</key>
<true/>
<key>StartInterval</key>
<integer>7200</integer>
<key>StandardErrorPath</key>
<string>/tmp/test</string>
<key>StandardOutPath</key>
<string>/tmp/testout</string>
</dict>
</plist>
I am running by:
$ launchctl unload com.nn.test.plist
$ launchctl load com.nn.test.plist
$ launchctl run com.nn.test
Result is cat /tmp/testout
display dialog "Hi"
While /tmp/test is empty.
Expected behaviour would be that a dialog opens just like when I run the command directly in the shell (which works) but it seems nothing is happening. What am I doing wrong and why do I not see any error messages in any error log?
Might this have to do with Mojave's enhanced security model? Can't AppleScript be run from launchd agents any more?

I think you are doubly-stringified!
You need:
<array>
<string>/usr/bin/osascript</string>
<string>-e</string>
<string>display dialog "Hi"</string>
</array>
and:
launchctl start com.nn.test

Related

How to start a launch agent on demand after the installation?

I've coded my launch daemon and a launch agent for macOS. When the app is installed, I need to run both the daemon and the agent. I place the .plist for the deamon into /Library/LaunchDaemons and then run (as admin):
launchctl load /Library/LaunchDaemons/com.example.MyDaemon.plist
and since the plist has:
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
the daemon starts up right away.
But I'm struggling to do the same with my launch agent. Here's it's plist that I place into /Library/LaunchAgents directory for it to start for every user and also in the login screen:
<?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>LimitLoadToSessionType</key>
<array>
<string>Aqua</string>
<string>LoginWindow</string>
</array>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>com.example.MyAgent.plist</string>
<key>Program</key>
<string>/Library/PrivilegedHelperTools/com.example/MyAgent</string>
<key>ProgramArguments</key>
<array>
<string>-d</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
when I try to run it as:
launchctl load /Library/LaunchAgents/com.example.MyAgent.plist
I get an error:
Warning: Expecting a LaunchDaemons path since the command was ran as
root. Got LaunchAgents instead. launchctl bootstrap is a recommended
alternative. /Library/LaunchAgents/com.example.MyAgent.plist:
Path had bad ownership/permissions Load failed: 122: Path had bad
ownership/permissions
what am I doing wrong?

Luanchd not starting mopidy & UDP listener

I'm trying to write a Launchd script to execute a simple sh script that will 1) launch mopidy 2) mkfifo /tmp/mopidy.fifo 3) pass data from port 5555 into this file using socat.
I've tried setting up a mopidy.plist LaunchAgent that executes a mopidy.sh script file at login. I've verified that the LaunchAgent gets started correctly and that the script has execution permissions. I've also tried the Program Arguments approach by passing the script as a one-liner to /bin/bash, but when I try that I get errors logged saying that its unable to find socat.
mopidy.sh
nohup mopidy;
mkfifo /tmp/mopidy.fifo;
while :; do
socat -d -d -T 1 -u UDP4-LISTEN:5555 OPEN:/tmp/mopidy.fifo;
done
mopidy.plist
<!-- Starts mopidy server -->
<?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.me.mopidy.plist</string>
<key>Program</key>
<string>/Users/me/.config/scripts/mopidy.sh</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/me/logfile.log</string>
<key>StandardErrorPath</key>
<string>/Users/me/error_logfile.log</string>
</dict>
</plist>
I am able to execute the bash script normally without error from the command line, however it doesn't seem like the service is able to because the /tmp/modipy.fifo file never gets created and the listener is never made. The logfile and error_logfile are never populated either.
I was able to get it working by including environment variables. I don't fully understand this, but everything works now with the following:
<!-- Starts mopidy server -->
<?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.me.mopidy.plist</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/Users/me/.config/scripts/mopidy.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/me/logfile.log</string>
<key>StandardErrorPath</key>
<string>/Users/me/error_logfile.log</string>
</dict>
</plist>

CVS pserver in OS X Sierra times out intermittently

I recently migrated my cvs server from a very old mac to some new hardware. I found instructions for setting up Launch Services to run cvs pserver, and it works sometimes.
/Library/LaunchDaemons/cvspserver.plist contains this
<?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.apple.cvspserver</string>
<key>UserName</key>
<string>root</string>
<key>Program</key>
<string>/usr/local/bin/cvs</string>
<key>ProgramArguments</key>
<array>
<string>-f</string>
<string>--allow-root=/home/cvsroot</string>
<string>pserver</string>
</array>
<key>Sockets</key>
<dict>
<key>Listeners</key>
<dict>
<key>SockPassive</key>
<true/>
<key>SockServiceName</key>
<string>2401</string>
<key>SockType</key>
<string>stream</string>
</dict>
</dict>
<key>inetdCompatibility</key>
<dict>
<key>Wait</key>
<false/>
</dict>
</dict>
</plist>
CVS will work for a while, but sometimes I'll get:
cvs [update aborted]: connect to cvs(10.10.0.2):2401 failed: Operation timed out
Trying again sometimes works. If I do this:
sudo launchctl unload -w /Library/LaunchDaemons/cvspserver.plist
sudo launchctl load -w /Library/LaunchDaemons/cvspserver.plist
It'll work right away, but after a while the timeouts start again.
Any ideas? I don't even know how to debug this...
I now believe that the problem was that the server was going to sleep, and even though it was set to wake on network activity, that doesn't actually work. So I set it to never sleep and it's been reliable since then.

Launch Agent Not Starting

I’m trying to make a launch agent that starts a Python script. It should run when there’s a network connection but it doesn’t do that. launchctl list says it’s loaded:
launchctl list | grep test.Flopsey.DiscordMusicBot
- 0 test.Flopsey.DiscordMusicBot
When I start it with launchctl start test.Flopsey.DiscordMusicBot it works fine. The .plist file (which is stored under ~/Library/LaunchAgents) looks 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>test.Flopsey.DiscordMusicBot</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5</string>
<string>/path/to/MusicBot/run.py</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/bin:/usr/bin:/usr/local/bin</string>
</dict>
<key>StandardOutPath</key>
<string>/path/to/MusicBot/log.log</string>
<key>StandardErrorPath</key>
<string>/path/to/MusicBot/log.log</string>
<key>WorkingDirectory</key>
<string>/path/to/MusicBot</string>
<key>KeepAlive</key>
<dict>
<key>NetworkState</key>
<true/>
</dict>
</dict>
</plist>
I’m new to launchd and I followed this tutorial. I think the solution to my problem is very basic but I have no idea what it could be. I’ve also made another similar agent and it works fine (unlike the music bot it’s only one file).
Update
Thanks to #LCC’s comment I realised that using NetworkState doesn’t work anymore on OS X 10.10 and higher. Since the script exits when it can’t connect to the Internet I can just set KeepAlive to <true/> and set up a ThrottleInterval so launchd restarts the script after a cooldown if it couldn’t connect.

Launchd plist service is not shutting down

I have application i want to run as LaunchDaemon on OSX. My plist looks 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>KeepAlive</key>
<false/>
<key>Label</key>
<string>my.service</string>
<key>ProgramArguments</key>
<array>
<string>/servertest/MyService</string>
<string>-jvm</string>
<string>server</string>
<string>-nodetach</string>
<string>-outfile</string>
<string>out.txt</string>
<string>-errfile</string>
<string>err.txt</string>
<string>-verbose</string>
<string>-debug</string>
<string>-home</string>
<string>/System/Library/Frameworks/JavaVM.framework/Home</string>
<string>-cp</string>
<string>./lib/hsqldb.jar:./lib/myservice-wrapper.jar:./lib/commons-daemon-1.0.8.jar</string>
<string>my.service.DaemonMac</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/servertest/stderr.log</string>
<key>StandardOutPath</key>
<string>/servertest/stdout.log</string>
<key>WorkingDirectory</key>
<string>/servertest</string>
</dict>
</plist>
Service starts on load or when i call 'launchctl start my.service'. But it's not going down when i use 'launchctl stop my.service' or even unload plist. It remains in memory and runs as if nothing happened. Have no idea what could be the reason. Please, help!
Does your application daemonize itself (i.e. drop into the background)? If so, it's essentially detaching itself from launchd and hence preventing launchd from managing it.
EDIT: if the application isn't daemonizing itself, the next thing to look at is to see what launchd thinks is going on with launchctl list my.service. This should dump a list of properties of the daemon, including its PID (if launchd thinks it's running) and LastExitStatus (whether it exited successfully last time it ran). Does the PID correspond to the actual running process? Does the result change when you try to stop the service (esp. does the PID change to 0)? Does a process listing (e.g. with ps -axj) show any child processes living on after the parent exits?
Oh, and just to make sure: when managing LaunchDaemons, you need to use sudo launchctl (without the sudo, launchctl will try to manage LaunchAgents within your user session).
The file that worked for me is below. I've learned that my deamon must not detach itself from controling process and it has to be "OnDemand" so i could stop it when i want. I've made some shaman dances while working on it and though it's not clear to me at which point it began to work. Now it does.
<?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>KeepAlive</key>
<false/>
<key>Label</key>
<string>myserver</string>
<key>OnDemand</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/opt/MYServer/MYServer</string>
<string>-server</string>
<string>-outfile</string>
<string>/opt/MYServer/out.txt</string>
<string>-errfile</string>
<string>/opt/MYServer/err.txt</string>
<string>-verbose</string>
<string>-debug</string>
<string>-nodetach</string>
<string>-home</string>
<string>/System/Library/Frameworks/JavaVM.framework/Home</string>
<string>-cp</string>
<string>/opt/MYServer/lib/hsqldb.jar:/opt/MYServer/lib/my-wrapper.jar:/opt/MYServer/lib/commons-daemon-1.0.8.jar</string>
<string>my.service.DaemonMac</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/opt/MYServer/stderr.log</string>
<key>StandardOutPath</key>
<string>/opt/MYServer/stdout.log</string>
<key>WorkingDirectory</key>
<string>/opt/MYServer</string>
</dict>
</plist>

Resources