So I've been trying to write a launchctl daemon for rsync so that it backs up my laptop remotely every night.
The launchctl daemon runs fine, it uses the root user to call rsync, and rsync is instructed to use ssh, and grab the key file from my user directory. Here's where it gets interesting. No matter what I do, ssh throws the following error: rsync: Failed to exec ssh -i /Users/anthony/.ssh/id_rsa: No such file or directory (2)
The key is indeed there. If I call ssh on its own from the command line, I can use that key from both my user account and the root account. I'm assuming this is something to do with launchctl's scope, or privileges? Below is the plist file that launchctl is using. I'd really appreciate some help on this.
<?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>UserName</key>
<string>root</string>
<key>Label</key>
<string>com.anthony.remoteBackup</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>23</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/rsync</string>
<string>-azb</string>
<string>--exclude=.*</string>
<string>--exclude=.*/</string>
<string>--backup-dir="/home/anthony/Documents/Old Remote Backup/macbook_air/"</string>
<string>--suffix=.old</string>
<string>--delete</string>
<string>--delete-excluded</string>
<string>-e "ssh -i /Users/anthony/.ssh/id_rsa"</string>
<string>/Users/anthony/Documents</string>
<string>anthony@remote_domain_name:"/home/anthony/Documents/Remote Backups/macbook_air/"</string>
</array>
<key>StandardOutPath</key>
<string>/tmp/remote_backup_test</string>
<key>StandardErrorPath</key>
<string>/tmp/remote_backup_test</string>
</dict>
</plist>
here is the standard error from remote_backup_test
rsync: Failed to exec ssh -i /Users/anthony/.ssh/id_rsa: No such file or directory (2)
rsync error: error in IPC code (code 14) at /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54.120.1/rsync/pipe.c(86) [sender=2.6.9]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54.120.1/rsync/io.c(453) [sender=2.6.9]
I suspect the problem is how you're passing the arguments. The double-quotes you have in several arguments are shell syntax, but the elements of the
ProgramArguments
array don't get parsed by a shell, so they shouldn't be there. Most importantly, the space after-e
is intended to be parsed by a shell as an argument delimiter, so replace:with:
and just remove the double-quotes from the
--backup-dir=
and target (anthony@...
) arguments.