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.
Related
I want to run a python script every day at 7pm on a mac-based computer. I put together a script, but I'm not sure where to save it or where I can monitor progress. What can I do to turn this into a task-
<?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.example.nightlyscript</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/python</string>
<string>/path/to/script.py</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>19</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
</dict>
</plist>
According to this excellent article at townrdsdatascience.com, you need to put your property list in the ~/Library/LaunchAgents directory (which you can create in ~/Library if it doesn't already exist. The launchd man page further explains that you can put it in /Library/LaunchAgents if you want it to run for each user on your machine, or in /Library/LaunchDaemons to make it run across the whole system. Be sure to check your plist against the instructions in either of those sources -- I haven't looked to see if you've included everything that's needed. You'll also want to make your python script executable.
MacOS High Sierra, I have a plist I want to use with launchd.
I am trying to use this in ~/Library/LaunchDaemon but it is not working.
<?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.myscript.mac.plist</string>
<key>Program</key>
<string>/private/var/myscript.sh</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>LaunchOnlyOnce</key>
<true/>
</dict>
</plist>
When I use sudo lauchctl load com.myscript.mac.plist nothing is output.
No confirmation message, no error message, nothing. This is where I seem to have stalled.
The top-level folder private is hidden, in case that makes any difference.
What is wrong with my script? Why can I not get it to run?
Three possible reasons:
The Label in the plist must be specified without the extension: com.myscript.mac
If the daemon is located in the user library it must be loaded without sudo
The folder name is LaunchDaemons (with trailing s)
I have a Go program that is supposed to run as a daemon with minimal front-end for the user (just an icon in the system tray.)
The fact that it's written in Go doesn't really matter much, the main issue I have is getting a binary (that is already running) to run at startup on a Mac.
I can set the binary to run at startup like so:
cp daemon.plist ~/Library/LaunchAgents/daemon.plist
(cp the plist into the LaunchAgents directory)
launchctl load -w ~/Library/LaunchAgents/daemon.plist
(then load the plist with launchctl.)
And that works fine. The only issue is that launchctl load it starts another instance of the binary that is already running. I want to be able to enable (and disable) running the binary at startup for the binary that is running, without starting another instance of it.
And here's the .plist file if you want to see it:
<?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>daemon</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Daemon.app/Contents/MacOS/daemon</string>
</array>
<key>ProcessType</key>
<string>Interactive</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
I figured it out.
So first, the binary is running. It starts out as not enabled to run at startup. To initialize, you cp the plist to the ~/Library/LaunchAgents/ directory:
cp daemon.plist ~/Library/LaunchAgents/daemon.plist
And the 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>Label</key>
<string>daemon</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Daemon.app/Contents/MacOS/daemon</string>
</array>
<key>ProcessType</key>
<string>Interactive</string>
<key>RunAtLoad</key>
<false/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
NOTE: The RunAtLoad key is set to false.
Then we load it into launchctl:
launchctl load -w ~/Library/LaunchAgents/daemon.plist
It shouldn't load since RunAtLoad is set to false.
Then, we can enable and disable running at startup like so:
To enable:
Set RunAtLoad to true
cp the plist over
To disable:
Set RunAtLoad to false
cp the plist over
Kind of hacky, but it works.
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.
I need a way to automatically do a vagrant up command inside my directory /Users/user/Dropbox/Development/Homestead
Does anyone know how this can be achieved?
You can write an automator application (i.e. workflow) and in that application have it run the shell script with your desired vagrant command. Then go to System Preferences -> Accounts -> Login items and add that application as a login item.
With a LaunchD item. Put a file containing this in your /Library/LaunchDaemons directory:
<?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>UserName</key>
<string>user</string>
<key>Label</key>
<string>org.xyzzy.vagrantsrc</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/vagrant</string>
<string>up</string>
</array>
<key>RunAtLoad</key><true/>
<key>UserName</key><string>jenkins</string>
<key>WorkingDirectory</key><string>/Users/user/Dropbox/Development/Homestead</string>
</dict>
</plist>
It needs to be owned by root and called something.plist