The internet is full of usefull information that is accessable from everywhere. Unfortunately some information is only available for a certain period of time. For instance, while you can stream real-time tick data from stock markets, accessing historical data may only provide per-minute aggregates. Similarly, request for proposals (RFPs) are typically only available for a set period of time before they are taken down from the web.
This makes all sense because storage is not for free and the amount of data would grow over the top.
This time constrain brings me often to the situation that I start to collect data periodically. I collect the data on my laptop and would like to backup it to an external drive. For an efficent fetching procedure it is crucial to keep the recent data at hand on my laptop for comparison. While analysis or aggregations are performed on the mounted external ssd. My disk has a decent read and write capability (2000 MB/s).
Storyline
So every time the drive is connected to the laptop some kind of Time Machine routine should start and move all the recent data points to the external drive.
Since I work with a MacBook this seems to be best possible with a launchd
job. crontab
does not seem to be the way ahead.
Faild Attempt with Bash
Instead of using the AppleScript as describe next I first tried to start from launchd a bash script. The downfall were the file permission and giveing bash “Full Disk Access” was not a prefered option. Therefore, I switch to use AppleScript.
<key>Program</key>
<string>/Users/username/Scripts/external-volume-synch.sh</string>
AppleScript to Run rsync
The actual solution consists of an AppleScript that checks if the target disk RemovableDiskName
is mounted and uses rsync
with the archive mode to do the data sync.
set RemovableDiskName to "Extreme Pro"
tell application "System Events" to set MountedDisks to name of every disk
if RemovableDiskName is in MountedDisks then
try
do shell script "rsync -au '/Source/Path' '/Destination/Path'"
delay 1
on error e
display dialog "An error occured: " & e
end try
end if
The LaunchAgent
An agent is a process that runs on behalf of a user in the background. Contrary to daemons who run as part of the system. The agent description below contains the key startOnMount
set to true
. This will envoke the AppleScript when ever a disk is mounted.
<?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.custom.synch.external.ssd</string>
<key>LowPriority</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/com.custom.synch.external.stdout</string>
<key>StandardErrorPath</key>
<string>/tmp/com.custom.synch.external.stderr</string>
<key>WorkingDirectory</key>
<string>/Users/username/Documents</string>
<key>ProgramArguments</key>
<array>
<string>osascript</string>
<stirng>/Library/Scripts/Custom/external-volume-synch.scpt</string>
</array>
<key>StartOnMount</key>
<true/>
</dict>
</plist>
To load and enable the launchd use the launchctl
.
launchctl load -w ~/Library/LaunchAgents/com.custom.sync.external.ssd.plist
En voila, Plug in the target drive, check the logs and see if the files appear in the taget folder.
Side Notes
Frist: Although cron
is simple and extensivly used it is deprecated on OS X in flavor of launchd
(Link).
Second: For inspiration is the plist of Time Machine /System/Library/LaunchDaemons/com.apple.backupd-helper.plist
. Altough the StartOnMount
key is turned off and the helpers is listening to other LaunchEvents
. This is some thing for a future deep dive.