launchctl status returns 2 - macos

I'm trying to write a launchd script that will run a Python script every hour.
I created the following file in ~/Library/LaunchAgents/
com.b00tahead.engage-check.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.b00tahead.engage-check</string>
<key>ProgramArguments</key>
<array>
<string>/Library/Frameworks/Python.framework/Versions/3.5/bin/python3</string>
<string>Projects/engage_scripts/engage_check.py</string>
</array>
<key>StartInterval</key>
<integer>3600</integer>
</dict>
</plist>
I then run:
launchctl load ~/Library/LaunchAgents/com.b00tahead.engage-check.plist
launchctl start com.b00tahead.engage-check
When I run launchctl list it shows the process as:
PID Status Label
- 2 com.b00tahead.engage-check
I'm not exactly sure what that return code indicates. I can run the script just fine through the terminal as python3 Projects/engage_scripts/engage_check.py
The Python script writes some data to a .txt file on my desktop.
This is what launchctl list com.b00tahead.engage-check returns:
{
"LimitLoadToSessionType" = "Aqua";
"Label" = "com.b00tahead.engage-check";
"TimeOut" = 30;
"OnDemand" = true;
"LastExitStatus" = 512;
"Program" = "/Library/Frameworks/Python.framework/Versions/3.5/bin/python3";
"ProgramArguments" = (
"/Library/Frameworks/Python.framework/Versions/3.5/bin/python3";
"Projects/engage_scripts/engage_check.py";
);
};

My guess is that the argument in ProgramArguments should have an absolute path (not relative such as Projects/...).
In case of error, system log should be checked, e.g.
tail -f /var/log/system.log
or custom log can be used by specifying these lines:
<key>StandardOutPath</key>
<string>/var/log/myjob.log</string>
<key>StandardErrorPath</key>
<string>/var/log/myjob.log</string>
See: Debugging launchd Jobs section of Creating Launch Daemons and Agents page.

Related

AppleScript code to edit my plist

Using AppleScript, how can I edit key PhoneNumber to a new value and delete key UserActive?
I have read Apple's documentation, but I did not get any success. Thanks for 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>Person</key>
<dict>
<key>Adult</key>
<dict>
<key>Names</key>
<dict>
<key>MyName</key>
<dict>
<key>Adress</key>
<dict>
<key>Profissional</key>
<dict>
<key>CelNumber</key>
<integer>4</integer>
<key>PhoneNumber</key>
<integer>5</integer>
</dict>
<key>UserActive</key>
<integer>0</integer>
</dict>
for edit plist file it's more simple use /usr/libexec/PlistBuddy in your script you can with PlistBuddy
Clear type Clears out all existing entries, and creates root of type
type. See below for a list of types.
Print [entry]
Prints value of entry. If an entry is not specified, prints
entire file. See below for an explanation of how entry works.
Set entry value
Sets the value at entry to value.
Add entry type [value]
Adds entry with type type and optional value value. See
below for a list of types.
One example for see in Terminal window : Controller:IOPCIMatch from AMD5000Controller.kext or AMDRadeonX3000.kext
tell application "Terminal"
activate
do script "/usr/libexec/PlistBuddy -c \"Print :IOKitPersonalities:Controller:IOPCIMatch \" /System/Library/Extensions/AMD5000Controller.kext/Contents/info.plist;
/usr/libexec/PlistBuddy -c \"Print :IOKitPersonalities:AMDCedarGraphicsAccelerator\" /System/Library/Extensions/AMDRadeonX3000.kext/Contents/info.plist
"
end tell
tell application "Terminal"
activate
do script "/usr/libexec/PlistBuddy -c \"Print :IOKitPersonalities:Controller:IOPCIMatch \" /System/Library/Extensions/AMD5000Controller.kext/Contents/info.plist;
/usr/libexec/PlistBuddy -c \"Print :IOKitPersonalities:AMDCedarGraphicsAccelerator\" /System/Library/Extensions/AMDRadeonX3000.kext/Contents/info.plist
"
end tell

Is it possible to evaluate an expression in launchd's ProgramArguments array?

I have a ~/Library/LaunchAgents/setenv.JAVA_HOME.plist file which contains a /bin/launchctl call as follows:
<?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>setenv.JAVA_HOME</string>
<key>ProgramArguments</key>
<array>
<string>/bin/launchctl</string>
<string>setenv</string>
<string>JAVA_HOME</string>
<string>$(/usr/libexec/java_home -v1.8)</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>
Problem is, the $(/usr/libexec/java_home -v1.8) expression is not evaluated and instead the JAVA_HOME environment variable is assigned the literal value $(/usr/libexec/java_home -v1.8).
Question is: is it possible to compose my plist file so that the expression is evaluated and not treated as a literal value? And, if so, how?
As you've discovered, <string> entries are passed as string literals, but $(/usr/libexec/java_home -v1.8) is a bash shell expression. According to the launchd.plist documentation, ProgramArguments only takes an array of strings, so there does not appear to be any way of marking an argument as an expression.
However, I think the simple solution is to run /bin/bash with the -c argument, followed by the command line you want to execute.
<?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.so</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v1.8)</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>ServiceIPC</key>
<false/>
</dict>
</plist>

At my end with launchd

Hi all and thanks for reading this. I have the below launchd 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.me.sendip</string>
<key>Program</key>
<string>/Users/me/Documents/sendip.sh</string>
<key>StartInterval</key>
<integer>60</integer>
<key>StandardErrorPath</key>
<string>/Users/me/Desktop/sendiperr.log</string>
<key>StandardOutPath</key>
<string>/Users/me/Desktop/sendip.log</string>
</dict>
I also have the below script
/Users/me/Documents/Scripts/ip.sh | mail -s "Laptop ip" me#gmail.com
I have tried troubleshooting with all the tools here. The script fires with an empty log file on boot but after that nothing.
Someone please help. I am totally stumped and I am sure its something silly. Much appreciated.
It turns out launchd abandons the sub processes of the script I was trying to run. this is a common problem as it turns out. Found the answer here.
Hmmm. I run a script at hourly intervals using the following plist in 10.9.5.
<?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>Disabled</key>
<false/>
<key>Label</key>
<string>org.myorg.mytask</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/php</string>
<string>/path/to/myscript.php</string>
</array>
<key>QueueDirectories</key>
<array/>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>5</integer>
</dict>
<key>WatchPaths</key>
<array/>
</dict>
</plist>
That runs every hour at 5 minutes past the hour.
I think for you're looking to run once a minute, right? So your version would be:
<?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>Disabled</key>
<false/>
<key>Label</key>
<string>com.me.sendip</string>
<key>ProgramArguments</key>
<array>
<string>/Users/me/Documents/sendip.sh</string>
</array>
<key>QueueDirectories</key>
<array/>
<key>StartInterval</key>
<integer>60</integer>
<key>WatchPaths</key>
<array/>
</dict>
</plist>
You may need to start the service by running this command in Terminal: (it will require your password)
sudo launchctl load com.me.sendip
Edit: Here is a script with more explicit logging:
#!/bin/bash
OUTFILE='/Library/Logs/com.whatever.sendip.log'
ERRFILE='/Library/Logs/com.whatever.sendip.err.log'
SCRIPT='/Users/me/Documents/Scripts/ip.sh'
TARGET_EMAIL='me#gmail.com'
TARGET_SUBJECT='Laptop ip'
VERBOSE=1
if [ "$VERBOSE" -ne 0 ]; then
date >>"$OUTFILE"
date >>"$ERRFILE"
echo -n 'Current user: ' >>"$OUTFILE"
whoami >>"$OUTFILE"
fi
INFO=$("$SCRIPT" 2>>"$ERRFILE")
echo "$INFO" | mail -s "$TARGET_SUBJECT" "$TARGET_EMAIL" >>"$OUTFILE" 2>>"$ERRFILE"
ERROR_CODE="$?"
if [ "$ERROR_CODE" -ne 0 ]; then
echo "Result: Error Code $ERROR_CODE" >>"$OUTFILE"
echo "Info: $INFO" >>"$OUTFILE"
elif [ "$VERBOSE" -ne 0 ]; then
echo "Result: Success" >>"$OUTFILE"
echo "Info: $INFO" >>"$OUTFILE"
fi

Inside shell script: write Python output to file works from terminal, "Input stream is empty" when running from launchd

I wrote a short shell script to write the contents of an Evernote note to a file with Geeknote, which runs under python:
#!/bin/bash
/usr/bin/python /Users/me/Git/geeknote/geeknote.py find --search "Hobbies To Do" > /dev/null
/usr/bin/python -u /Users/me/Git/geeknote/geeknote.py show "Hobbies To Do" | tee /Users/me/Programming/output.txt
The script works fine when I run it from terminal (it writes the output of the second python command to output.txt), although ideally I'd like the script to run periodically on its own. So I tried creating a .plist/LaunchAgent to run the script, but when I do that the only thing that gets written to output.txt is Input stream is empty...can't figure out why. Right now 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>Label</key>
<string>com.me.geektoolcron</string>
<key>ProgramArguments</key>
<array>
<string>/Users/me/Programming/script.sh</string>
</array>
<key>StartInterval</key>
<integer>10</integer>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
You could try replacing the second python command with something like echo a or replacing tee with a redirection. A script like this worked for me with the same plist:
#!/bin/bash
date | tee /tmp/f
launchd also supports directing stdout to a file:
<key>StandardOutPath</key>
<string>/Users/me/Programming/output.txt</string>

pandoc via launchd -- getting error: "pdflatex not found. pdflatex is needed for pdf output

I am trying to generate a pdf document from a markdown document every 90 seconds. I have set up a task in launchd to handle this for me. Unfortunately, I am getting an error announcing that pdflatex can't be found even though I can invoke it from the command line. Here is the entire contents of ddd_publisher.sh, which is the file that launchd runs every 90 seconds:
/usr/local/bin/pandoc -o /Users/Jon/dev/intercontinental/ddd.pdf /Users/Jon/dev/intercontinental/ddd.ddd
The program runs every 90 seconds, but it writes the following line to stderr:
pandoc: pdflatex not found. pdflatex is needed for pdf output.
If I type pdflatex -v at the command line it tells me that it is installed:
pdfTeX 3.1415926-2.4-1.40.13 (TeX Live 2012)
Here is my launchd 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>ddd.intercontinental.publisher</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Jon/dev/intercontinental/ddd_publisher.sh</string>
</array>
<key>StandardErrorPath</key>
<string>/Users/Jon/dev/intercontinental/ddd.stderr</string>
<key>StandardOutPath</key>
<string>/Users/Jon/dev/intercontinental/ddd.stdout</string>
<key>StartInterval</key>
<integer>90</integer>
The solution was to add the path for pdflatex to the bash script, as follows:
#!/bin/bash
PATH=$PATH:/usr/texbin
/usr/local/bin/pandoc -o /Users/Jon/dev/intercontinental/ddd.pdf /Users/Jon/dev/intercontinental/ddd.ddd

Resources