macOSで定期的にプログラムを動作させるとき,cronではなく,launchctlを使ってLaunchAgentsを登録するのが一般的です。
 日々のバックアップなど,root権限が必要な,システム的なプログラムについては,LaunchDaemonsを登録することになります。
 LaunchDaemonsを使うとき,気付かずにハマってしまったことがあるので,ここにメモしておきます。

LaunchDaemonsの登録

 /Library/LaunchDaemonsにプログラムの起動情報を書き入れたXMLを配置し,launchctlで登録します。このとき,セキュリティの観点から,XMLのオーナーはrootにしておかなければならないようになっているようです。

 XMLファイルの書き方は,ここでは割愛します。

$ chown root jp.example.daemons.plist
$ launchctl load jp.example.daemons.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>jp.example.daemons</string>
    <key>Username</key>
    <string>someone<!-- root以外で動作させる場合はユーザー名を入れる --></string>
    <key>ProgramArguments</key>
    <array>
      <string>/bin/bash</string>
      <string>/usr/local/bin/backup.sh</string>
      <!-- 実行ファイルとパラメータを書いていく -->
    </array>
    <!-- 他にも色々なパラメータがあります -->
  </dict>
</plist>

注意点

 バックアップなどではシェルスクリプトを使うことになると思われますが,さらに外部のプログラムを実行する場合,予めパスを通しておく必要があります。

 スクリプトはログイン状態で実行されるわけではないので,最低限のパスしか設定されていない場合があります。

 自分の環境では,以下のようになっていました。

PATH=/usr/bin:/bin:/usr/sbin:/sbin

 Homebrewでインストールしたプログラムは/usr/local/binに配置されることが多いため,それらのプログラムを利用する場合は,自作したスクリプトの中でパスを通しておく必要があります。

PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin ; export PATH
# exportしなくても動作するようです