0

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>
  • 2
    Why are you using cat to copy files? Use the key ProgramArguments with the absolute path to the script. And the absolute paths to the source file and destination file within your script. – fd0 Aug 4 '16 at 10:49
  • Thanks @fd0 ! With the changes you suggested (absolute paths) the script now runs successfully from any directory. unfortunately LaunchAgent is still not functional... I have added the updated file for reference. – danny_C_O_T_W Aug 4 '16 at 13:04
  • The script should contain absolute paths as well (or set PATH itself at the beginning), not only the LaunchAgent plist. Also cating a file to another looks kind of strange, just use cp (if you want to keep the source file) or mv (if you only want to rename it). – nohillside Aug 4 '16 at 14:08
  • 1
    Ah, and why are you using <key>ProgramArguments</key> here? – nohillside Aug 4 '16 at 14:10
1
  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.

  • thanks! this looks like a more sustainable/neater solution. after a system restart my initial attempts worked, but I think I will adapt to this protocol. – danny_C_O_T_W Aug 5 '16 at 9:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .