Problem: Looks like the drive is mounted after the script has finished. If anyone knows a fix for this, please post a message here.
Detect the USB
Firstly you'll need to set up a system to detect when your USB drive is plugged in, and run a script when it is. We will use udev to achieve this.
Create the file /etc/udev/rules.d/91-local.rules and copy this into it:
Code:
SUBSYSTEMS=="usb", KERNEL=="sd??", ACTION=="add", RUN+="/usr/local/bin/USB %k"
This will run a script located at /usr/local/bin/USB and pass it %k (the kernel name for the device detected).
Now we'll need to test that this works - create a script at /usr/local/bin/USB and copy this into it:
Code:
#!/bin/bash
echo 'Hello World!' >>"/home/<username>/Desktop/udev.out"
exit
(obviously replacing <username> with your username)
Now add the execute bit (sudo chmod +x /usr/local/bin/USB), and finally test that everything works by plugging in a USB drive. If everything does work you should see a file called udev.out appear on your desktop, upon opening it you should see that it contains the text 'Hello World!' Do not continue until this part of the system works.
Find Your USB Identifier
We will need a way to identify your USB so that we can treat it differently to other USBs. If you do not plan to give your USB any special treatment, feel free to skip to the next section.
We will use the disk identifier to identify your USB, you can find this by plugging in your USB and running sudo fdisk -l - if you're not sure which one in the list is yours then look at the amount of GBs and the number of partitions each disk has.
Create the Backup Script
Finally the actual backup script (/usr/local/bin/USB), you can write your own in a language of your choice, or use mine, written in bash. If you use mine you'll have to change the variables at the top and install rsync. Here it is:
[BASH]
PHP Code:
#!/bin/bash
exec &> /var/log/udev-USB
MY_DRIVE_UUID='????-????' # My USB disk identifier
OUT='/home/bob/USB-Backup' # Where the backups are stored
SIZE_LIMIT='1GB' # Size gets rounded to nearest unit
USERNAME='bob' # Username to chown the backup to
function error { echo "$@, aborting." >&2; exit 1; }
drive_kernel="${1}"
if [ -z "${drive_kernel}" ]; then error "Could not detect drive kernel"; fi
echo "drive_kernel=${drive_kernel}"
drive_uuid=$(blkid -c /dev/null -o value -s UUID /dev/${drive_kernel})
if [ -z "${drive_uuid}" ]; then error "Could not detect drive UUID"; fi
echo "drive_uuid=${drive_uuid}"
if [ "${drive_uuid}" != "${MY_DRIVE_UUID}" ]; then error "Not my drive"; fi # Only backup my drive
drive_size=`df -B "${SIZE_LIMIT}" | grep "^/dev/${drive_kernel}" | awk '{print $3}'`
if [ -z "${drive_size}" ]; then error "Could not detect drive contents"; fi
echo "drive_size=${drive_kernel}"
if [ "${drive_size}" > 1 ]; then error "Drive contents too big"; fi
drive_mountpoint=`df | grep "^/dev/${drive_kernel}" | awk '{print $6}'`
if [ -z "${drive_mountpoint}" ]; then error "Could not detect drive mountpoint"; fi
echo "drive_mountpoint=${drive_mountpoint}"
if [ ! -d "${OUT}" ]; then mkdir -p "${OUT}"; fi # If $OUT does not exist, then make it
if [ "${drive_uuid}" == "${MY_DRIVE_UUID}" ]
then
rsync -ac "${drive_mountpoint}/"* "${OUT}/My USB/" &&\
chown -R "${USERNAME}" "${OUT}/My USB/"
else
rsync -ac "${drive_mountpoint}/"* "$OUT/${drive_uuid}/" &&\
chown -R "${USERNAME}" "${OUT}/${drive_uuid}/"
fi
exit $?
P.S.
If you have any trouble following this guide or want to offer a suggestion on how it could be improved, please just post here. If it helped you, add a few tags - it makes it easier for other people to find it that way.
See Also: http://www.reactivated.net/writing_udev_rules.html.
Thanks to flaconindy.
Bookmarks