Want launchd to run a script weekly, but it is running it daily instead

bashlaunchd

I wanted to write a simple launchd job that runs a script every Monday morning at 7:00 am. The goal is to pull an image from tapmusic.net that catalogs my last.fm listening habits from the prior week. The daemon runs properly and is able to execute the script just fine, and the script does exactly what I want it to. The issue is that the job is being executed every day at midnight, not Monday at 7. This is my first time trying out something like this, and I tried to follow templates on developer.apple.com and ones floating around the net, but I'm really unsure of how I can fix this problem. Here is the *.plist file that I'm running:

<?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>local.lastfm_chart</string>
        <key>Program</key>
        <string>/scripts/lastfm_chart.sh</string>
        <key>StartCalendarInterval</key>
        <dict>
            <key>Hour</key>
            <integer>7</integer>
            <key>Minute</key>
            <integer>0</integer>
            <key>Weekday</key>
            <integer>1</integer>
        </dict>
    </dict>
</plist>

Like I said, I've been able to load and run the job just fine, just not at the right time.

Also, my system.log file is getting bombarded by a message and looks like this:

Jun 15 08:54:46 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 2 seconds. Pushing respawn out by 8 seconds.
Jun 15 08:54:57 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 3 seconds. Pushing respawn out by 7 seconds.
Jun 15 08:55:07 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 2 seconds. Pushing respawn out by 8 seconds.
Jun 15 08:55:45 --- last message repeated 2 times ---
Jun 15 08:55:45 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 8 seconds. Pushing respawn out by 2 seconds.
Jun 15 08:55:50 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 2 seconds. Pushing respawn out by 8 seconds.
Jun 15 08:56:12 --- last message repeated 1 time ---
Jun 15 08:56:12 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 3 seconds. Pushing respawn out by 7 seconds.
Jun 15 08:56:34 --- last message repeated 1 time ---
Jun 15 08:56:34 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 4 seconds. Pushing respawn out by 6 seconds.
Jun 15 08:56:43 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 2 seconds. Pushing respawn out by 8 seconds.
Jun 15 08:57:07 --- last message repeated 1 time ---
Jun 15 08:57:07 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 5 seconds. Pushing respawn out by 5 seconds.
Jun 15 08:57:15 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 3 seconds. Pushing respawn out by 7 seconds.
Jun 15 08:57:25 ***-MBP com.apple.xpc.launchd[1] (local.lastfm_chart): Service only ran for 2 seconds. Pushing respawn out by 8 seconds.

I'm not sure what this signifies, either.

I'm on mojave 10.14.6, if that matters.

Adding an edit to include the bash script that is being executed:

#!/bin/sh


now=`date -v -7d +"%Y-%m-%d"`
curl "https://tapmusic.net/collage.php?user=gas_giant&type=7day&size=4x4&caption=true" -o /Users/****/Documents/Music/last.fm\ Listening\ Reports/tuneage_${now}.jpg

Best Answer

From your log it looks like you are running as a daemon, not an agent. A daemon is meant to run constantly, while an agent only once.

So your .plist file should be in ~/Library/LaunchAgents. Once it is in that directory then you still have to load it using launchctl load <filename>.

I'm also wondering if you have a leftover process from a previous attempt as the log looks like you have KeepAlive set but not the .plist. That's why the mention of respawn.

Next, I was wondering about the script path - is the absolute path actually /scripts/lastfm.sh. If you are using the Program key rather than the ProgramArguments key it has to be an absolute path.

Assuming that you have not loaded into System space but correctly into your user space then I'd start by having a look at what launchctl thinks is happening behind the scenes.

  1. Find out your user ID by running id -u (mine is 502)
  2. List the information for your job launchctl print gui/502/local.lastfm_chart

This will include an event triggers section that should show you exactly when launchctl thinks it should run the command. It will also show you the command, if keepalive is set and other useful information.

Oh, and keep out the RunAtLoad unless you actually want to RunAtLoad. The best way to test things is to give it a kickstart - launchctl kickstart gui/502/local.lastfm_chart will run your service.

The same is true with StandardErrorPath and StandardOutPath - rather than constantly changing the .plist file you can use the launchctl debug command to alter these once before you kickstart, so:

  1. launchctl debug gui/502/local.lastfm_chart —-stdout —-stderr will set stdout and stderr to your terminal session for the next invocation of the service.
  2. launchctl kickstart gui/502/local.lastfm_chart runs it with those settings and then they disappear.