After following steps, including permissions for the shell script and loading the launchctl plist file as proscribed in the article, I find that I am unable to make shell script execute when using the ‘launchctl run (the shell script path)’ command. The following are the specifics procedures I followed from the article:
created shell script example:
#!/bin/bash
say date "+%H:%M"
placed it at:
~/bin/speakDate.sh
gave shell script permission using:
chmod 750 ~/bin/speakDate.sh
saw that the shell script works fine when running it from Terminal
Thanks for suggestion. Actually, I originally used the explicit path name but wished to be disrcrete when posting at the forum. I have to compliment you for discovering my full path call. Anyhow, I did try to redo the plist path as you recommended and I still get the same behavior: after entering ‘launchctl start’ nothing happens, except the plist name is unloaded automatically.
Also, in some of the steps shown in my original post you will see that I sometimes misspell ‘launchctl.’ This is not the culprit–just my normal humanity asserting itself.
According to your plist file, you aren’t doing anything wrong, you’re just not doing anything. The OnDemand key defaults to true anyway, so it is unnecessary, but still, your agent is not being asked to perform any task at all, so it will never be called.
I recommend that you add something like this:
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>23</integer>
<key>Minute</key>
<integer>20</integer>
</dict>
to have your agent fire at a specific time to see if it is going to function. You can also use the StartInterval key to have the agent fire every N seconds using this format:
<key>StartInterval</key>
<integer>N</integer>
Once you have your plist file set up to actually perform something based on a schedule, or another event, you should be able to see if indeed your agent is functional.
For the record, here’s my message to the Apple Discussion page that wraps up the issue:
Thanks for the suggestion to use Console.app. I have never used this tool before and it’s nice to know that it exists. I suppose it is a system or unix log file for error messages. Your idea that the plist’s relative path to the shell script needed to be changed to a full path was also suggested by a member of MacScripter. I actually put the relative path in for posting on this forum, thinking it would make my steps more general. Originally, I did use a full path. The problem–which I could see clearly in the Console.app file–was that the full path had a blank space at the end. How subtle is that? Once I re-entered the full path taking care to eliminate the extra space, the ‘start’ command worked like a champ.
Craig: I just noticed your post as I am writing this. Your plist example looks interesting–the periodic mechanism–and I will take a look at it. Note, however, that my plist–the one used in the magazine article–contains a reference to a shell script that actually speaks the date (see step 1 in by original post).
Since continuing onward with my project, I found another glitch that perhaps someone can help with. If I put a shell script path with a space in it (/Library/Application(space here)Support/VocabAware/VocabAnalysis/vocabAware.sh) into the launchctl plist it won’t load. The console.log shows:
VocabAwareStart: execvp(“/Users/awnispel/Library/Application\ Support/vocabAware.sh”, …): No such file or directory
Note that I have granted permission for the shell script to execute already. The launchctl list works fine when the shell script path does not have a space. Any help would be appreciated.
Thanks for providing the “Don’t escape special characters in the ProgramArguments key” rule. This is the type of gotcha that makes a forum like this so helpful. My plist seems to make a successful call to my shell script in it’s new location now. I suppose the documentation for this information is out there. Perhaps I should have gone to the mac developers documents on plist protocols.
The system is very finicky about the Program Argument paths within the plist file. Launcht would not allow me to load my plist file if the Program Argument path 1) contained any back-slash escape characters 2) contained a full-path prefix 3) did not identify an actual program (this one is pretty intuitive) 4) if the program file does not have run permission using, for example, chmod a+x (file path). For example, the following Program Argument fails the first two criteria:
There is a back-slash between ‘Application Support’, and the absolute plist path file prefix ‘/Users/awnispel’ should not be there. I have no idea why the absolute path prefix is wrong–especially since suggestion by StefanK (2008-02-24 08:47:23 am) states the opposite, however I have tested this and it seems to be a problem. The Program Argument that works for me is:
These errors are easy to trigger since you are likely to use your Terminal’s ‘drag-file-to-terminal’ to get the path address. When you do this, beware that the resulting POSIX path will show an unwanted back-slashes before path spaces and your absolute path prefix–as in my ‘/Users/awnispel’. When you attempt to load your plist file with these extras, you will see an error message.
I didn’t say the opposite. Obviously your executable is in the main library /Library and not in the user library /Users/myUser/Library.
In both libraries there is an Application Support folder.
And of course the special characters in the path must not be escaped by backslashes, because it’s not the shell syntax, where arguments are separated by space characters,
it’s just a path within XML tags.
Stephan, thanks for pointing out that there are two possible paths that contain the library folder. This clears up the mystery about why my home folder prefix would not work for the Program Path. While this may be obvious to you, to many of us who don’t program on a daily basis, these ambiguities are thickets where we get snagged. Likewise for the problem of backslashes. There is no way to know that the plist file uses XML paths unless you work with this stuff frequently. Most of us probably assume it uses POSIX paths which is not such a far-out assumption. That’s why there are forums like Macscripter to help everyone out. Your help is appreciated, however I caution you about what may seem obvious.
I just wanted to make clear, that the shell syntax is a special case.
By default a POSIX path (slash separated) may contain space characters, therefore there is no extra note in the launchd documentation.
In a command line a space character is defined as the parameter separator, therefore paths must be escaped.
And for checking a path you really don’t need to be a professional programmer