I created some scripts to backup my Samsung Galaxy S2 to my Fedora 16 system without pressing any keys or even touching the mouse. It works like this:
To backup a SGS2, you go to settings > applications > usb tools on the phone, and click the button. You then connect it to a usb cable. At that moment, two removable devices become visible to the Linux system: one for the SD card, one for the built-in memory. But they still contain no media. Only when you press another button on the phone, the "media are inserted in the devices", triggering a "change" action with the udev daemon.
Configuration of the udev daemon
Create a file /etc/udev/rules.d/71-android-backup.rules:
SUBSYSTEM=="block", ACTION=="change", ENV{ID_SERIAL}=="Android_UMS_Composite_XXXXXXXXXXXXXXXX-0:0", ENV{DISK_MEDIA_CHANGE}=="1", ENV{ID_FS_TYPE}=="vfat", RUN+="/usr/local/bin/androidbackup" |
Whenever a (virtual) medium is inserted, a udev change action is triggered. Actually, it gets triggered multiple times, but we only need the one that has the environment variable DISK_MEDIA_CHANGE=1 set.
Action to perform
The action triggered is /usr/local/bin/androidbackup and all parameters are in the environment. So let's create that file. I use a rsnapshot-like operation to backup my data, but without actually using rsnapshot.
#!/bin/bash function msg { /usr/bin/logger -t android "$1" DISPLAY=:0 qdbus $dbusRef setLabelText "$1" DISPLAY=:0 qdbus $dbusRef Set "" value $2 } if [ "$1" != "FORKED" ]; then $0 FORKED & exit 0 fi if [ -f /etc/sysconfig/androidbackup ]; then . /etc/sysconfig/androidbackup else echo /etc/sysconfig/androidbackup does not exist exit 0 fi #debug disabled: #set > /tmp/android/`date +%s`.$RANDOM dbusRef=`kdialog --display :0 --progressbar "Backup android..." 100` msg "Attach $DEVNAME $ACTION $ID_SERIAL" 0 if [ ! -e $DESTINATION ]; then # I could mkdir -p, but sometimes $DESTINATION could just be a network location that's offline msg "Android will not be backed up: $DESTINATION is not okay" 0 exit 0 fi mkdir -p /mnt/android mount $DEVNAME /mnt/android rc=$? if [ $rc -ne 0 ]; then msg "Problem mounting $DEVNAME to /mnt/android: $rc " 0 mount | grep android 2>&1 | logger -t androidbackup exit 0 fi if [ "`mount |grep -i /mnt/android`" == "" ]; then msg "Cannot find /mnt/android in mount table" 0 exit 0 fi msg "Remove old backup" 8 [ -e $DESTINATION/backup.30 ] && rm -rf $DESTINATION/backup.30 msg "Start backup" 10 for i in `/usr/bin/seq 30 -1 2`; do if [ -e $DESTINATION/backup.$((i-1)) ]; then msg "mv $DESTINATION/backup.$((i-1)) $DESTINATION/backup.$i" 11 mv $DESTINATION/backup.$((i-1)) $DESTINATION/backup.$i fi done msg "Copy" 40 [ -e $DESTINATION/backup.0 ] && /bin/cp -al $DESTINATION/backup.0 $DESTINATION/backup.1 mkdir -p $DESTINATION/backup.0/ msg "Start rsync" 40 /usr/bin/rsync -az --numeric-ids --delete --hard-links /mnt/android/ $DESTINATION/backup.0/ touch $DESTINATION/backup.0/ chown -R $CHOWN $DESTINATION/backup.0 umount /mnt/android msg "Done" 100 exit 0 |
Since that file refers to /etc/sysconfig/androidbackup, let's also make that file:
#next line defines the location of all backups DESTINATION=/home/geeklab/.androidbackup #next line defines the owner of all files copied CHOWN=geeklab |