diff --git a/rpi-clone b/rpi-clone index 6b28835..3cae887 100755 --- a/rpi-clone +++ b/rpi-clone @@ -1,6 +1,18 @@ #!/bin/bash -VERSION=1.2 +VERSION=1.4 +# Version 1.4 2015/08/16 +# * add -n (--dry-run) option for rsync +# * add -u (--uuid) option to auto-detect disk by UUID. +# System on reboot may change its disk symbol mapping, thus dangerous. +# It is more secure searching by UUID. +# Version 1.3 2015/06/18 +# * add -q (quiet) option for use as cron script +# -q only works with existing backups, +# it won't initialize the destination SD card partitions with dd! +# Please initialize the destination SD card from the shell (by hand) +# for the first time. +# This is to protect you for accidentally overwriting a SD Card. # Version 1.2 2015/02/17 # * add -x option # * tweak some echo messages @@ -16,6 +28,9 @@ VERSION=1.2 PGM=`basename $0` RSYNC_OPTIONS="--force -rltWDEgopt" +BLKID="/sbin/blkid" +TAIL="/usr/bin/tail" +HEAD="/usr/bin/head" # List of extra dirs to create under /mnt. OPTIONAL_MNT_DIRS="clone mnt sda sdb rpi0 rpi1" @@ -59,11 +74,14 @@ fi usage() { echo "" - echo "usage: $PGM sdN {-f|--force-initialize} {-v|--verbose} {-x}" + echo "usage: $PGM sdN {-f|--force-initialize} {-v|--verbose} {-x} {-q|--quite}" echo " Example: $PGM sda" echo " -v - list all files as they are copied." + echo " -n - do a dry-run of rsync." + echo " -u - UUID of one of a disk partition, used when disk is not passed." echo " -f - force initialize the destination partitions" echo " -x - use set -x for very verbose bash shell script debugging" + echo " -q - use quiet modus to schedule the script as a cron script" echo "" echo " Clone (rsync) a running Raspberry Pi file system to a destination" echo " SD card 'sdN' plugged into a Pi USB port (via a USB card reader)." @@ -96,6 +114,7 @@ usage() } VERBOSE=off +QUITE_FOR_CRON=false while [ "$1" ] do @@ -104,6 +123,13 @@ do VERBOSE=on RSYNC_OPTIONS=${RSYNC_OPTIONS}v ;; + -n|--dry-run) + RSYNC_OPTIONS=${RSYNC_OPTIONS}n + ;; + -u|--uuid) + shift + DST_DISK=$($BLKID -U $1 | $TAIL -c 5 | $HEAD -c 3) + ;; -f|--force-initialize) FORCE_INITIALIZE=true ;; @@ -113,6 +139,9 @@ do -h|--help) usage ;; + -q|--quite) + QUITE_FOR_CRON=true + ;; *) if [ "$DST_DISK" != "" ] then @@ -143,6 +172,12 @@ fi unmount_or_abort() { + if [ "$QUITE_FOR_CRON" = "true" ] + then + echo "Sorry, mounted devices in quite_cron mode is not allowed." + echo -e "Aborting!\n" + exit 0 + fi echo -n "Do you want to unmount $1? (yes/no): " read resp if [ "$resp" = "y" ] || [ "$resp" = "yes" ] @@ -246,6 +281,12 @@ if [ "$DST_BOOT_PARTITION_TYPE" != "$SRC_BOOT_PARTITION_TYPE" ] || \ [ "$DST_ROOT_PARTITION_TYPE" != "$SRC_ROOT_PARTITION_TYPE" ] || \ [ "$FORCE_INITIALIZE" = "true" ] then + if [ "$QUITE_FOR_CRON" = "true" ] + then + echo "Sorry, now new disk setup allowed in quite_cron mode." + echo -e "Aborting!\n" + exit 0 + fi CLONE_MODE="rsync all files to $DST_DISK root file system" echo "" if [ "$FORCE_INITIALIZE" = "true" ] @@ -352,8 +393,14 @@ echo "===============================" # If this is an SD card initialization, can watch progress of the clone # in another terminal with: watch df -h # -echo -n "Final check, is it Ok to proceed with the clone (yes/no)?: " -read resp + +if [ "$QUITE_FOR_CRON" != "true" ] +then + echo -n "Final check, is it Ok to proceed with the clone (yes/no)?: " + read resp +else + resp="y" +fi if [ "$resp" != "y" ] && [ "$resp" != "yes" ] then echo -e "Aborting the disk clone.\n" @@ -369,7 +416,7 @@ fi # Mount destination filesystems. echo "=> Mounting $DST_ROOT_PARTITION ($DST_ROOT_VOL_NAME) on $CLONE" -if ! mount $DST_ROOT_PARTITION $CLONE +if ! mount -t ext4 $DST_ROOT_PARTITION $CLONE then echo -e "Mount failure of $DST_ROOT_PARTITION, aborting!\n" exit 0 @@ -381,9 +428,9 @@ then fi echo "=> Mounting $DST_BOOT_PARTITION on $CLONE/boot" -if ! mount $DST_BOOT_PARTITION $CLONE/boot +if ! mount -t vfat $DST_BOOT_PARTITION $CLONE/boot then - umount $CLONE + umount -t ext4 $CLONE echo -e "Mount failure of $DST_BOOT_PARTITION, aborting!\n" exit 0 fi @@ -476,14 +523,16 @@ echo "" # Eg. modify $CLONE/etc/hostname, $CLONE/etc/network/interfaces, etc # if I'm cloning into a card to be installed on another Pi. # -echo -n "Hit Enter when ready to unmount the /dev/$DST_DISK partitions..." -read resp - +if [ "$QUITE_FOR_CRON" != "true" ] +then + echo -n "Hit Enter when ready to unmount the /dev/$DST_DISK partitions..." + read resp +fi echo "unmounting $CLONE/boot" -umount $CLONE/boot +umount -t vfat $CLONE/boot echo "unmounting $CLONE" -umount $CLONE +umount -t ext4 $CLONE echo "==============================="