Code:
#! /bin/bash
# name: drive-image.sh, disk image copy script
# by: Jan Zumwalt - www.neatinfo.com
# ver: Jan 4, 2009
# remarks:
# -e = enable interpretation of backslash codes
# -n = disable newline at end of line (i.e. user input prompt)
# exit 1 = error, exit 0 = success
IMAGE_FROM=hda # the drive or partition we will copy (save).
IMAGE_TO=hdc # the target (were it will be saved)
# Pretty ANSI writing
OFF="\033[0m"
BOLD="\033[1m"
DIM="\033[2m"
YELLOW="\033[1;33m"
FkeyRead () # character read from keyboard is in $ANSWER
{
oldstty=$(stty -g)
stty -icanon -echo min 1 time 1
ANSWER=$(dd bs=1 count=1 2>/dev/null)
stty "${oldstty}"
}
while :
do
clear
echo -en "\n"
echo -en "\t\t\t$BOLD Drive Image Copy\n"
echo -en "\t\t\t by:Jan Zumwalt\n"
echo -en "\t\t\t$YELLOW NeatInfo.com - Ver Jan 04, 2009$OFF\n\n"
echo -en "\t\t This program uses the dd command to copy an entire drive,\n"
echo -en "\t\t or partition.$YELLOW If a single mistake is made while manually\n"
echo -en "\t\t typeing the dd command, all your data may be destroyed.$OFF \n"
echo -en "\t\t This script allows you to carefully plan ahead, then \n"
echo -en "\t\t repeat the process fearlessly. It also makes a nice\n"
echo -en "\t\t log for future reference.\n"
echo -en "\n"
echo -en "\t\t This program is set to copy from [$IMAGE_FROM] to [$IMAGE_TO].\n"
echo -en "\t\t You can change what is copied by opening the script\n"
echo -en "\t\t with a text editor and changing two variables near the\n"
echo -en "\t\t beginning of the script.\n"
echo -en "\n\t\t\t\t $YELLOW($IMAGE_FROM --> $IMAGE_TO)$OFF\n"
echo -en "\n$BOLD"
echo -en "\t\t.------------------------------------------------. \n"
echo -en "\t\t| Please select from one of these options. |\n"
echo -en "\t\t| |\n"
echo -en "\t\t|$YELLOW 1) Make the drive image $OFF$BOLD |\n"
echo -en "\t\t|$YELLOW 2) View file systems list $OFF$BOLD |\n"
echo -en "\t\t|$YELLOW 3) Set up program and create a shortcut $OFF$BOLD |\n"
echo -en "\t\t|$YELLOW 4) About this program (brief instructions) $OFF$BOLD |\n"
echo -en "\t\t|$YELLOW 5) Quit $OFF$BOLD |\n"
echo -en "\t\t'------------------------------------------------'\n"
echo -en "\n"
echo -en "\t\t$BOLD What would you like to do? 1,2,3,4,5 $YELLOW[1]$OFF "
FkeyRead
case $ANSWER in
1|"")
clear
echo -en "\n"
echo -en "\t\t OK! Here we go...\n"
# see if log directory exist
if [ ! -d $HOME/logs ]; then
echo -en "\n\n\t\t*** Log directory not found ***\n"
echo -en "\n\t\t Should I create the directory I need for logs ($HOME/logs)? "
FkeyRead
case $ANSWER2 in
[Yy])
mkdir $HOME/logs
esac
fi
# opportunity to add comment to log file
echo -en "\n\t\t You may now add a comment for the log file...\n"
echo -en "\t\t "
read ANSWER
echo -e "\t\t"$ANSWER >> $HOME/logs/drive-image.log
# save backup starting time image = /boot/vmlinuz
echo -en "\t\t Backup start time = " `date`"\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\t\t Backing up...\n"| tee -a "$HOME/logs/drive-image.log"
# The actual backup is done here. Included are some possible options.
# These options are machine specific - here is some of mine...
# dd if=/dev/hda1 of=/dev/hdc1 # win partition
# dd if=/dev/hda7 of=/dev/hdc7 # linux partition
# dd if=/dev/hda of=/dev/hdc # entire IDE slot 1 drive to IDE slot 3 <default>
dd if=/dev/$IMAGE_FROM of=/dev/$IMAGE_TO bs=1024k | tee -a "$HOME/logs/drive-image.log"
# save backup ending time
echo -en "\t\t Backup end time = " `date`"\n"| tee -a "$HOME/logs/drive-image.log"
# success - show log file and exit
echo -en "\t\t Script completed successfully.\n\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\t\t *******************************************\n"
echo -en "\t\t *** Here is a copy of your log file ***\n"
echo -en "\t\t *******************************************\n"
cat $HOME/logs/drive-image.log
echo -en "\n\n\t\t Press the ${YELLOW}[ANY]${OFF} key to exit. "
FkeyRead
echo -en "\n\n"
exit 0;;
2) # set up program and create a shortcut
clear
echo -en "\n\n"
echo -en "\t.------------------- Here is your mounted media ------------------.\n"
echo -en "\t. .\n"
fdisk -l | pr -o10 -t | cut -c1-75
echo -en "\t. .\n"
echo -en "\t'-------------------------------------------------------------------'\n"
echo -en "\t. .\n"
echo -en "\t. This is a listing of your MOUNTED media. You may have other .\n"
echo -en "\t. media attached and available. The file system or devices ${YELLOW}do${OFF} .\n"
echo -en "\t. ${YELLOW}not have to be mounted${OFF} to work.$BOLD The \"dd\" command that this .\n"
echo -en "\t. program uses can be VERY dangerous.$OFF There is no way of knowing .\n"
echo -en "\t. what the intent of the user is, and in less than 1 second .\n"
echo -en "\t. permanent data loss will occur! So, please be very carfull! .\n"
echo -en "\t. .\n"
echo -en "\t'-------------------------------------------------------------------'\n"
echo -en "\n\t\t Press ${YELLOW}[ANY]${OFF} key to return to main menu."
FkeyRead
clear ;;
3) # set up program and create a shortcut
clear
if [ ! -d $HOME"/logs" ] ; then # if log dir not made, create it
mkdir $HOME"/logs"
echo -en "\n\t\t Checking and setting up script " `date`"\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\t\t Missing personal log dir, I made one at $HOME/logs\n"| tee -a "$HOME/logs/drive-image.log"
else
echo -en "\n\t\t Checking and setting up script " `date`"\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\t\t Found personal log dir at $HOME/logs\n"| tee -a "$HOME/logs/drive-image.log"
fi
if [ ! -d $HOME"/bin" ] ; then # if bin dir not made, create it
mkdir $HOME"/bin"
echo -en "\t\t Missing personal bin dir, I made one at $HOME/bin\n"| tee -a "$HOME/logs/drive-image.log"
else
echo -en "\t\t Found personal bin dir at $HOME/bin\n"| tee -a "$HOME/logs/drive-image.log"
fi
if [ ! -f $HOME"/bin/drive-image.sh" ] ; then # if prog not in bin dir, copy it there
cp $0 $HOME"/bin/drive-image.sh" # copy myself to the bin dir
echo -en "\t\t I copied script to bin dir at $HOME/bin\n"| tee -a "$HOME/logs/drive-image.log"
else
cp $0 $HOME"/bin/drive-image.sh" # copy myself to the bin dir
echo -en "\t\t I overwrote script in bin dir at $HOME/bin\n"| tee -a "$HOME/logs/drive-image.log"
fi
chmod ugo+x "$HOME/bin/drive-image.sh" # make sure script will execute
echo -en "\t\t Confirmed script is executable at $HOME/bin\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\n"
START_DIR=$PWD # save current dir
echo -en "\t\t Going to your desktop and creating shortcut...\n"| tee -a "$HOME/logs/drive-image.log"
cd $HOME"/Desktop" # goto desktop to make shortcut
{
echo "[Desktop Entry]"
echo "Comment="
echo "Comment[en_US]="
echo "Encoding=UTF-8"
echo "Exec='$HOME/bin/drive-image.sh'"
echo "GenericName="
echo "GenericName[en_US]="
echo "Icon=exec"
echo "MimeType="
echo "Name=drive-image"
echo "Name[en_US]=drive-image"
echo "Path="
echo "StartupNotify=true"
echo "Terminal=true"
echo "TerminalOptions=\s--noclose"
echo "Type=Application"
echo "X-DCOP-ServiceType=none"
echo "X-KDE-SubstituteUID=false"
echo "X-KDE-Username="
} > "drive-image.desktop"
chmod ugo+x "drive-image.desktop" # make shortcut executable
cd $START_DIR # be nice and return to our original dir
echo -en "\t\t Created desktop shortcut...\n"| tee -a "$HOME/logs/drive-image.log"
echo -en "\n\t\t Press ${YELLOW}[ANY]${OFF} key to return to main menu."
FkeyRead
clear ;;
4) # we are here because the user wanted to quit
clear
echo -en "\n"
echo -en "\t .--------------------- $BOLD About This Program $OFF ---------------------.\n"
echo -en "\t . .\n"
echo -en "\t . This is a very brief explanation of how this program works. .\n"
echo -en "\t . This program will work with all file systems. They do not .\n"
echo -en "\t . have to be mounted to work. This program's primary use is to .\n"
echo -en "\t . copy complete drive images to identical drives. This will .\n"
echo -en "\t . provide an exact backup that is bootable (including MS Win). .\n"
echo -en "\t . If you are not interested in a bootable backup, it may be .\n"
echo -en "\t . better to use the tar command which offers compact file size. .\n"
echo -en "\t . $YELLOW This program can be VERY dangerous.$OFF There is no way of .\n"
echo -en "\t . knowing what the users intent is. A typo error can cause .\n"
echo -en "\t . permanent data loss in less than 1 second! .\n"
echo -en "\t . .\n"
echo -en "\t . IDE drives are the most common, so I'll use it as an example. .\n"
echo -en "\t . Most mother boards provide 4 IDE drive ports attached by 2 .\n"
echo -en "\t . cables. Each cable can have two drives plugged on to them. .\n"
echo -en "\t . UNIX controls them with alias names hda,hdb,hdc, and hdd. .\n"
echo -en "\t . Each partition on a drive can be designated by adding a .\n"
echo -en "\t . number. hda1 is the first partition on the first drive, hda3 .\n"
echo -en "\t . is the third partition of the same drive. .\n"
echo -en "\t . .\n"
echo -en "\t . more... pg 1 of 3 .\n"
echo -en "\t .----------------------------------------------------------------.\n"
echo -en "\n\t\t Press $YELLOW [ANY]$OFF key to continue... "
FkeyRead
clear
echo -en "\n"
echo -en "\t .--------------------- $BOLD About This Program $OFF ---------------------.\n"
echo -en "\t . .\n"
echo -en "\t . \"dd\" is the UNIX command to make a file or partition image. .\n"
echo -en "\t . The \"dd\" command uses IF (in file) and OF (out file) as file .\n"
echo -en "\t . system parameters. To completely copy the 1st IDE drive to .\n"
echo -en "\t . the 2nd drive, we would use this command... .\n"
echo -en "\t . $YELLOW dd if=/dev/hda of=/dev/hdb $OFF .\n"
echo -en "\t . Because we did not give partition numbers, the whole 1st .\n"
echo -en "\t . drive will be copied to the entire 2nd drive. .\n"
echo -en "\t . To copy a specific partition we must use the partition .\n"
echo -en "\t . number. Suppose we would like to copy the 1st partition of .\n"
echo -en "\t . IDE-3 (the \"c\" drive) and have it go to partion 4 of the .\n"
echo -en "\t . same drive. We would use this command... .\n"
echo -en "\t . $YELLOW dd if=/dev/hdc1 of=/dev/hdc4 $OFF .\n"
echo -en "\t . Be forwarned that if the two partitions are not the same .\n"
echo -en "\t . size, bad things can happen. You usually are all right if .\n"
echo -en "\t . you copy a small partition to a big one, but copying a big .\n"
echo -en "\t . one to a small one usually results in data corruption. .\n"
echo -en "\t . .\n"
echo -en "\t . more... pg 2 of 3 .\n"
echo -en "\t .----------------------------------------------------------------.\n"
echo -en "\n\t\t Press $YELLOW [ANY]$OFF key to continue... "
FkeyRead
clear
echo -en "\n"
echo -en "\t .----------------------------------------------------------------.\n"
echo -en "\t . .\n"
echo -en "\t . To make selecting the file systems easy, I made two ,\n"
echo -en "\t . variables to hold the drive definitions. They are located .\n"
echo -en "\t . near the beginning of the program listing. Here is how the .\n"
echo -en "\t . actual \"dd\" command looks using variables... .\n"
echo -en "\t . $YELLOW dd if=/dev/\$IMAGE_FROM of=/dev/\$IMAGE_TO $OFF .\n"
echo -en "\t . UNIX is very generious in file system support, so this .\n"
echo -en "\t . script can be used for SATA, SCSII, and USB drives too. I .\n"
echo -en "\t . have not tried other devices such as memory cards, but I .\n"
echo -en "\t . can not see any reason they should not work just as well. .\n"
echo -en "\t . .\n"
echo -en "\t . Here are some examples I use with my 250gb development sys. .\n"
echo -en "\t . IMAGE_FROM=hda, IMAGE_TO=hdc # entire \"A\" to \"C\" drive .\n"
echo -en "\t . IMAGE_FROM=hda1, IMAGE_TO=hdc1 # MS Windows partition .\n"
echo -en "\t . IMAGE_FROM=hda7, IMAGE_TO=hdc7 # linux partition .\n"
echo -en "\t . .\n"
echo -en "\t . Future enhancements will probably include a modest menu .\n"
echo -en "\t . so that manual text editing is not needed to select the .\n"
echo -en "\t . file systems. At the shell prompt, type$YELLOW man fdisk$OFF for some .\n"
echo -en "\t . interesting information. I hope this is of some use :) .\n"
echo -en "\t . .\n"
echo -en "\t . $BOLD Jan Zumwalt - NeatInfo.com $OFF .\n"
echo -en "\t . .\n"
echo -en "\t . pg 3 of 3 .\n"
echo -en "\t .----------------------------------------------------------------.\n"
echo -en "\n\t\t Press $YELLOW [ANY]$OFF key to continue... "
FkeyRead
clear ;;
5|[QqXx]) # we are here because the user wanted to quit
clear
echo -en "\n\n"
echo -en "\t\t OK! I am quiting...\n"
echo -en "\n\t\t Press $YELLOW [ANY]$OFF key to exit... "
FkeyRead
echo -en "\n\n"
exit 1;;
*) # the users response does not make sense so...
clear
echo -en "\n\n"
echo -en "\t\t$BOLD Please enter ${YELLOW}1,2,3,4,5 $OFF \n"
echo -en "\n\t\t Press $YELLOW [ANY]$OFF key to try again... "
FkeyRead
echo -en "\n\n"
clear ;;
esac
done
exit 1