0

I have a MySQL backup task that I've set up using this script.

When I run it manually with sh /{FILEPATH}/backup.sh it runs fine, but when I've added a plist with the task into LaunchDaemons and loaded it to launchctl, its throwing an error.

The task begins to run (as evidenced by the Backing up MySQL databases output), but is then erroring when its attempting to connect to the database.

From xxxx@xxxx.local  Wed Sep 17 07:00:03 2014
X-Original-To: xxxx
Delivered-To: xxxx@xxxx.local
From: xxxx@xxxx.local (Cron Daemon)
To: xxxx@xxxx.local
Subject: Cron <xxxx@xxxxc> /{FILEPATH}/backup.sh
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=xxxx>
X-Cron-Env: <USER=xxxx>
X-Cron-Env: <HOME=/Users/xxxx>
Date: Wed, 17 Sep 2014 07:00:01 +0100 (BST)

Loading config file (/{FILEPATH}/mysql-backup.conf)
Backup directory exists (/{FILEPATH}/2014-09-17)
Backing up MySQL databases...
    - {database name}...
/{FILEPATH}/backup.sh: line 82: --host=xx.xxx.xx.xx: command not found
Error on or near line 79; exiting with status 1
/{FILEPATH}/backup.sh: line 42: -N: command not found

The line the error is on is:

$MYSQLDUMP --host=$HOST --user=$USER --password=$PASS --default-character-set=utf8 --skip-set-charset --routines --disable-keys --force --single-transaction --allow-keywords $database > ${BACKDIR}/${SERVER}-MySQL-backup-$database-${DATE}.sql

and then it errors again on this function:

function checkMysqlUp() {
    $MYSQL -N -h $HOST --user=$USER --password=$PASS -e status
}
trap checkMysqlUp 0

This is my .plist file

<?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>EnvironmentVariables</key>
    <dict>
        <key>LANG</key>
        <string>en_US.UTF-8</string>
    </dict>
    <key>Label</key>
    <string>local.database.backup</string>
    <key>Program</key>
    <string>/{FILEPATH}/backup.sh</string>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>00</integer>
        <key>Minute</key>
        <integer>07</integer>
    </dict>
</dict>
</plist>

I've checked multiple threads on errors when using launchctl, and have made sure it has the correct permissions, etc. and the file path is also definitely correct (as the file does start running before it errors)

martoncsukas
  • 2,077
  • 20
  • 23

1 Answers1

0

In your regular login shell it works so you must have these commands in your path:

# mysql-backup.sh
28 MYSQL=${MYSQL:-`which mysql`}
29 MYSQLDUMP=${MYSQLDUMP:-`which mysqldump`}
30 PHP=${PHP:-`which php`}

while launchtl does not. (I believe which is silent on STDOUT when nothing is found.)

Options:

  1. A simple general solution is to type which mysql and which mysqldump and which php to find the paths in your shell and then add the PATH:

# mysql-backup.sh or mysql-backup.conf PATH=[path1]:[path2]:[path3]:$PATH

  1. Alternatively, you could set each command explicitly by adjusting and uncommenting them:

# (mysql-backup.conf) 35 # Custom path to system commands (enable these if you want use a different 36 # location for PHP and MySQL or if you are having problems running this script) 37 PHP="/opt/local/bin/php" 38 MYSQL="/opt/local/bin/mysql" 39 MYSQLDUMP="/opt/local/bin/mysqldump"

  1. A final alternative is to fix launchtl's PATH: launchctl environment manipulation (this makes sense if this script is one of many things you intend to automate on the system.)
Community
  • 1
  • 1
lossleader
  • 13,182
  • 2
  • 31
  • 45
  • Thanks lossleader, I was running the backup from a server volume which wouldn't have the path names defined on there. I've decided to move the `sh` files to my local desktop to keep the path, and then save the backups to the Volume. I'll check back tomorrow morning (once the task has ran) to confirm whether it was a path issue. –  Sep 30 '14 at 16:37