MacOS Catalina launchd can't open input file error - macos

Why won't launchd load my zsh program? I'm befuddled. My testplisterror.log gives me this error:
/bin/zsh: can't open input file: /Users/controlroom/Desktop/Bin/testplist.zsh -- below is my com.testplist.plist file located in the LaunchAgents 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>Label</key>
<string>com.testplist.plist</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>/Users/controlroom/Desktop/Bin/testplist.zsh</string>
</array>
<key>StartInterval</key>
<integer>30</integer>
<key>StandardOutPath</key>
<string>/Users/controlroom/Desktop/testplist.log</string>
<key>StandardErrorPath</key>
<string>/Users/controlroom/Desktop/testplisterror.log</string>
</dict>
</plist>
Here is my testplist.zsh file:
#!/bin/zsh
date >> ~/Desktop/launchdtest.txt

So this is because of a TCC error but because a script doesn't have a GUI you won't get an error. So as stated from Gordan Davisson, Apple has some TTC guidelines. These specific folders are TCC protected in Catalina:
~/Desktop,
~/Documents,
~/Downloads,
iCloud Drive,
third-party cloud storage, if used,
removable volumes,
network volumes.
https://eclecticlight.co/2020/01/16/a-guide-to-catalinas-privacy-protection-3-new-protected-locations/
"Logic would suggest that you could add the script to the Full Disk Access list, but I think you’ll find that you can’t, because it only accepts apps and executables." So the snag here is that currently you can't add a .zsh script to Full Disk Access List because of Apples TCC."

While #nwood21's answer is accurate, for future searchers who would like to run a script automatically, but are irked by the prospect of giving their script/shell/etc. Full Disk Access permissions (and dealing with the resulting security implications), there is another option:
/tmp and /Users/Shared are accessible to scripts launched via .plist (as well as cron-jobs), without the need for Full Disk Access
Confirmed in Aug 2022 on MacOS Monterrey.

Okay first, in order to launchd to grab a file you must add:
<key>UserName></key>
<string>usernamehere</string>
In other words, the program has to run as a username—if you don't have this it won't find the file.
Second, you must add:
<key>GroupName</key>
<string>wheel</string>
Third -- sometimes 3rd party commands won't execute properly in your script unless you add the
<key>EnvironmentalVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/bin:...etc.</string>
</dict>
For one reason or another it can't find executables of 3rd party CLI apps if you don't have this present in your script.
Because the syntax can be difficult and error prone I highly suggest using LaunchControl app to do this. It is an extremely useful piece of software!

Related

MacOS: Use getxattr/setxattr from a Finder Sync Extension

I want to use setxattr/getxattr from a Finder Sync Extension on OSX 10.12.6, but the calls fail with errno==1, which is EPERM. Finder sync extensions run in a sandbox, so I guess I need to request permissions. No amount of googling and documentation browsing uncovered information so far.
The files I want to access are owned by myself, and setting attributes with the xattr command line utility succeeds and produces the expected result.
So the question is: Which permissions/entitlements do I need to give the sandbox, or is this possible at all?
I basically want to store the sync status in the extended attributes (clean, modified, syncing) and select the correct badge for requestBadgeIdentifierForURL based on that. A lower priority non-sandboxed process goes over files and updates the attributes.
The alternative would be to use a separate database to store sync status and I'm going to use that if the xattr doesn't work out.
Edit: Added entitlements 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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<true/>
<key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
</plist>
The original entitlements file that comes with the sample is just
<key>com.apple.security.files.user-selected.read-only</key>
which didn't work either.
I added a test project to GitHub https://github.com/JensRestemeier/SyncExtensionTest
You are not specifying the path in the entitlement dic.
This is what it should look like:
<key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
<array>
<string>/</string>
</array>
This will give you access to all folders on the system.

Playing audio from OS X launchd daemon

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>

Sonatype Nexus - Service not starting on launch - MAC

Okay so following the instructions here
http://books.sonatype.com/nexus-book/reference/install-sect-service.html
I take the example 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.sonatype.nexus</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/nexus/bin/nexus</string>
<string>console</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
and stick it in my /Library/LaunchDeamons folder (I have also tries /System/Library/LaunchDeamons to no avail).
I have set the permissions on the file as specified in the documentation and I can even load the file manually using :
sudo launchctl load /Library/LaunchDaemons/com.sonatype.nexus.plist
However this does not start the service.
I can start the Nexus instance manually using this command from the terminal.
/usr/local/nexus/bin/nexus console
However on reboot of the device this service is not being launched and I still have to go back into the Terminal and manually call the command to start the Nexus instance.
Can anyone point me in a direction that might fix this? (Brand new to LaunchDeamons)
The console output is shown
Thanks
Aiden
This is most likely a permissions issue. The two options you have are to run Nexus as root user. This is not advisable for servers but might be okay for your local development purposes.
If thats the case you have to set the RUN_AS_USER in the nexus startup script to root and have Nexus installed in a folder root has access to (any really therefore) .. I suggest to use /opt
Better would be to create a specific user e.g. named 'nexus' and set the RUN_AS_USER to that name and make sure the user has full access to the Nexus installation (nexus folder and sonatype work folder).

Converting cron to launchd - MAILTO

Migrating from an old mac to a new one.
Trying to migrate the user crontab I had on the old mac.
Now I know I can probably get cron to run by creating /etc/crontab - but given that apple has deprecated it in favour of launchd - I thought I'd take a swing at migrating my crontab to launchd plist files. Always fun to learn something new :)
The crontab isn't that hard - I tend to set up shell scripts that do the work and then just call them at scheduled times.
I can call these fine from the plist at the same times - no issues.
But - at the top of my crontab I had MAILTO=my-gmail-email-address - so that instead of sending mail to the local user on the box's mail spool it sent them to gmail for me.
I can't see that you can configure this for a launchd plist file.
So - before I go modify all my scripts to redirect all output to tmp files then mail the tmp file (would have to do this in quite a few scripts) - is there a way to do this at the launchd level?
I'm afraid launchd(8) does not support mailing of stdout/stderr out of the box. Here's a workaround:
Redirect output via StandardOutPath and StandardErrorPath to files in a dedicated directory. Then setup a job which mails every file in this directory. Trigger this job with the QueueDirectories key. Make sure this script removes the files after mailing them.
one way to convert to launchd is the lazy way (how i do it)
You pay $0.99 for Lingon from the app store; then you can just fill out a few fields and it makes the launchd...
otherwise:
a launchd would look 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>name of launchd</string>
<key>ProgramArguments</key>
<array>
<string>[terminal command to execute]</string>
</array>
<key>RunAtLoad</key>
<[(true)/(false)]/>
<key>StartCalendarInterval</key>
<dict>
[any of these options are removable]
[for everyday remove the Day and Weekday tags]
<key>Day</key>
<integer>[day of the month]</integer>
<key>Weekday</key>
<integer>[day of the week 0-7 - (sunday=0);]</integer>
<key>Hour</key>
<integer>[hour of day (military time)]</integer>
<key>Minute</key>
<integer>[minute]</integer>
</dict>
</dict>
</plist>
any of the [] are either comments (must be removed) or a list of options
Use of the launchctl command would be used to mount the launchd

Creating a timed launchd plist

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.

Resources