Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 61 additions & 12 deletions rpi-clone
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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)."
Expand Down Expand Up @@ -96,6 +114,7 @@ usage()
}

VERBOSE=off
QUITE_FOR_CRON=false

while [ "$1" ]
do
Expand All @@ -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
;;
Expand All @@ -113,6 +139,9 @@ do
-h|--help)
usage
;;
-q|--quite)
QUITE_FOR_CRON=true
;;
*)
if [ "$DST_DISK" != "" ]
then
Expand Down Expand Up @@ -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" ]
Expand Down Expand Up @@ -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" ]
Expand Down Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 "==============================="
Expand Down