Here’s the copy-icloud-photos
script I use to backup my photos stored on iCloud to my Synology NAS:
#!/bin/bash
args=(
--delete
--human-readable
--no-perms
--partial
--progress
--times
-v
)
src="/Users/jyc/Pictures/Photos Library.photoslibrary/originals/"
|
I added find
recently because it’s annoying to accidentally backup temporary photos, like screenshots, that only live in my iPhone’s Camera Roll for a minute or so before I delete them.
I have launchd run that script daily using a configuration plist at ~/Library/LaunchAgents/jyc.copy-icloud-photos.service
:
Disabled
Label
copy-icloud-photos
ProgramArguments
/usr/local/bin/fdautil
exec
/Users/jyc/bin/copy-icloud-photos
StandardErrorPath
/tmp/copy-icloud-photos.err
StandardOutPath
/tmp/copy-icloud-photos.out
StartInterval
86400
I set it up via LaunchControl, which is a third-party shareware GUI for launchd that also provides the fdautil
wrapper script that makes it possible for the copy-icloud-photos
script to have full disk access.
I think it’s possible to get this to work without LaunchControl but I haven’t tried.
Unfortunately a big caveat is that this will back up recently deleted photos until they are truly deleted by iCloud.
Here’s some lists filenames of non-deleted non-hidden photos under ~/Pictures/Photos Library.photoslibrary/originals/
when run on the database at ../Photos.sqlite
:
select substr(ZFILENAME, 1, 1) || '/' || ZFILENAME
from ZASSET
where ZTRASHEDSTATE = 1 and ZHIDDEN = 0;
… but even when I grant bash
, copy-icloud-photos
, and sqlite3
Full Disk Access in System Settings > Privacy & Security, I can’t get it to work.
I thought I might just need to grant my script Photos access as well, but that doesn’t work.
Maybe Apple really is trying to block all programmatic access except through PhotoKit.