Launch Agent not running Bash File

bashlaunchdpathterminal

I have a bash script imagecopy.sh that backups images which are located in a subdirectory with a prepended date string: this works perfectly fine when I execute it from the directory it resides in – /Users/danny/Library/Caches/.

The script is

#!/usr/bin/env bash
cat himawaripy/latest.png > himawaripy/output/$(date "+%Y.%m.%d-%H.%M.%S").png

I have also added the directory where the script is located to my $PATHusing nano .profile and confirmed this using echo $PATH.

/Users/danny/Library/Caches:/Users/danny/anaconda/bin:/Library/Frameworks/Python.framework/Versions/3.4/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Library/TeX/texbin

I would like to run the bash script periodically using a LaunchAgent, located in /Users/danny/Library/LaunchAgents.

The LaunchAgent file com.user.imagecopier.plistreferences the script location by the lines..

..other code

<key>Program</key>
<string>imagecopy.sh</string>

...etc

I presume there is a mistake linking the LaunchAgent file to the script, any suggestions would be greatly appreciated.

Edit: Updated LaunchAgent File as Suggested

<?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.imagecopier</string>

  <key>ProgramArguments</key>
  <array>
    <string>/Users/danny/Library/Caches/imagecopy.sh</string>
  </array>

  <key>Nicer</key>
  <integer>1</integer>

  <key>StartInterval</key>
  <integer>60</integer>

  <key>RunAtLoad</key>
  <true/>

</dict>
</plist>

Best Answer

  1. To store a shell script in a Caches folder is very uncommon!
  2. If you use absolute paths in your script and the plist you don't have to add obscure paths to your PATH variable.

Clean up your .profile/.bash_profile file and remove the /Users/danny/Library/Caches: part!

Create a bin folder in your user folder and put in a script with the name imagecopy.sh. The content of the script is:

#!/bin/sh
cp /Users/danny/Library/Caches/latest.png /Users/danny/Documents/output/$(date "+%Y.%m.%d-%H.%M.%S").png

Create an appropriate output folder. In the example above I use ~/Documents/output.

Create the file /Users/danny/Library/LaunchAgents/com.user.imagecopier.plist with the content:

<?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.imagecopier</string>
    <key>Nicer</key>
    <integer>1</integer>
    <key>Program</key>
    <string>/Users/danny/bin/imagecopy.sh</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/tmp/com.user.imagecopier.stderr</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.user.imagecopier.stdout</string>
    <key>StartInterval</key>
    <integer>60</integer>
</dict>
</plist>

The file /tmp/com.user.imagecopier.stderr will show any error (e.g. if the output folder is missing or no latest.png is available)

Load the file with:

launchctl load -w /Users/danny/Library/LaunchAgents/com.user.imagecopier.plist

If the launch agent works properly you can remove the part

    <key>StandardErrorPath</key>
    <string>/tmp/com.user.imagecopier.stderr</string>
    <key>StandardOutPath</key>
    <string>/tmp/com.user.imagecopier.stdout</string>

of the plist.