Skip to content

Instantly share code, notes, and snippets.

@jez-nav
Created August 25, 2022 21:17
Show Gist options
  • Save jez-nav/3f13b1132ab8e291ae3a99ea1cb02879 to your computer and use it in GitHub Desktop.
Save jez-nav/3f13b1132ab8e291ae3a99ea1cb02879 to your computer and use it in GitHub Desktop.
Backup and Restore FAT formatted flash drive
#!/usr/bin/env bash
# FatBack v0.1
#
# Backup and Restore FAT formatted flash drive
# This tool is used for backing up a bootable CompactFlash formatted in FAT32. It will create
# a compressed ZSTD image which can be later restored back.
#
# Copyright 2021 jeznav
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# NOTICE: This script has not been tested on Hard-disks or any other storage mediums. Not tested on
# Linux, and Windows WSL. USE AT YOUR OWN RISK!
#
## Usage:
##
##
arg1=$1
SOURCE_DEVICE=""
TARGET_NAME=""
check_os(){
if [ "$(uname)" != "Darwin" ]; then
echo "This script only runs on macOS!"
exit 1
fi
echo "Checking for sudo...$EUID"
if [ "$EUID" != 0 ]; then
echo "Please run this script in sudo!"
exit 1
fi
}
check_tools() {
printf "Checking for %s..." "$1"
if which "$1" &>/dev/null; then echo "Ok"; else echo "not found. Aborting! $2"; exit 1; fi
sleep 0
}
help(){
echo "Usage: $0 device"
}
version(){
echo "FatBack v0.1 (C) 2021 jeznav"
}
show_devices(){
diskutil list | grep -e 'image\|external\|FAT'
}
verify_device(){
echo "Listing FAT devices:"
show_devices
if ! show_devices | grep "$1" &>/dev/null; then
echo "Could not find $1";
exit 1
else
while true; do
SOURCE_DEVICE=$(show_devices | grep "$1" | cut -d' ' -f1)
read -r -p "Is the source device $SOURCE_DEVICE correct? " yn
case $yn in
[Yy]* ) true; break;;
[Nn]* ) echo "Aborting..."; exit;;
* ) echo "Please answer yes or no.";;
esac
done
fi
}
select_target_name(){
identifier=$(echo "$1" | cut -d'/' -f3)
TARGET_NAME=$(show_devices | grep "$identifier" | grep "FAT" | awk '{print $3}')
SOURCE_SIZE=$(show_devices | grep "$identifier" | grep "FAT" | awk '{print $4}' | cut -d'.' -f1)
while true; do
read -r -p "Do you want to use $TARGET_NAME as target filename? (Yes/No/Cancel) " ync
case $ync in
[Yy]* ) true; break;;
[Nn]* ) read -r -p "Enter target filename: " TARGET_NAME; break;;
[Cc]* ) echo "Canceling..."; exit;;
* ) echo "Please answer yes or no.";;
esac
done
}
dump_device(){
echo "Dumping $SOURCE_DEVICE to $TARGET_NAME.img ..."
dd bs=1m if="/dev/rdisk2" | pv -s "$SOURCE_SIZE"G | dd of="$TARGET_NAME.img"
#dd if="$SOURCE_DEVICE" | pv -s "$SOURCE_SIZE"G | dd of="$TARGET_NAME.img"
}
mount_image(){
echo "Mounting Image"
}
zero_fill(){
echo "Zeroing empty spaces..."
}
get_used_space(){
echo "Getting used spaced..."
}
unmount_image(){
echo "Unmounting image..."
}
trim_image(){
echo "Trimming image..."
}
initialize(){
clear
check_os
check_tools "dd"
check_tools "zstd"
check_tools "mtools" "Please install mtools via homebrew -> 'brew install mtools'"
check_tools "pv" "Please install pv via homebrew -> brew install pv"
verify_device "$1"
select_target_name "$SOURCE_DEVICE"
while true; do
read -r -p "Ready to dump $SOURCE_DEVICE to $TARGET_NAME.img? " ync
case $ync in
[Yy]* ) true; break;;
[Nn]* ) echo "Aborting..."; exit;;
[Cc]* ) echo "Canceling..."; exit;;
* ) echo "Please answer yes or no.";;
esac
done
dump_device
}
if [ -z "$arg1" ]; then
help
else
if [[ "$arg1" == *"/dev/"* ]]; then
initialize "$arg1"
else
echo "Invalid syntax!"
help
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment