Skip to content

Instantly share code, notes, and snippets.

@grammy-jiang
Last active September 13, 2021 13:55
Show Gist options
  • Save grammy-jiang/9b34a5f88891642d5538030dbf32d4e6 to your computer and use it in GitHub Desktop.
Save grammy-jiang/9b34a5f88891642d5538030dbf32d4e6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
IMAGES="images"
PATTERN_RASPBERRY_PI_OS='\.\/images\/([0-9]{4}-[0-9]{2}-[0-9]{2})-(raspios)-([^-]*?)-(armhf)(-(full|lite)){0,1}\.zip'
PATTERN_UBUNTU='\.\/images\/ubuntu-[0-9.]*?-(preinstalled)-(desktop|server)-(arm64|armhf)\+raspi\.img\.xz'
PATTERN_OPENWRT='\.\/images\/openwrt-[0-9.]+-bcm27xx-bcm27[0-9]{2}-rpi(-[0-9])?-squashfs-factory\.img\.gz'
declare -A SUPPORT_OS
SUPPORT_OS=(
[Raspberry Pi OS]=$PATTERN_RASPBERRY_PI_OS
[Ubuntu]=$PATTERN_UBUNTU
[OpenWrt]=$PATTERN_OPENWRT
)
TF_CARD=""
OS_IMAGES=()
OS_IMAGE=""
# ------------------------------------------------------------------------------
# functions
# ------------------------------------------------------------------------------
function umount_tf_card() { # accept one argument about a mount point
mount_points=()
while IFS='' read -r line; do
mount_points+=("$line")
done < <(lsblk --noheadings --list "$1" | awk '{if (NF==7) {print $7}}')
for mount_point in "${mount_points[@]}"; do
umount "$mount_point"
printf "Umount the mount point %s\n" "$mount_point"
done
printf "\n"
}
function get_tf_card() { # get the tf card to write the image
# read all usb scsi devices
tf_cards=()
while IFS='' read -r line; do
tf_cards+=("$line")
done < <(lsblk --noheadings --scsi | awk '/(SD_MMC).*(usb)/{print "/dev/" $1}')
# echo all usb scsi devices information
printf "There are %s USB devices on the system now:\n\n" ${#tf_cards[@]}
lsblk "${tf_cards[@]}"
printf "\n"
# select the tf card to write the image
PS3="Select the tf card to write the image: "
select tf_card in "${tf_cards[@]}"; do
TF_CARD=$tf_card
break
done
umount_tf_card "$TF_CARD"
}
function get_images() { # accept one argument about a regular expression of image name
while IFS='' read -r line; do
OS_IMAGES+=("$line")
done < <(find ./$IMAGES -maxdepth 1 -type f -regextype posix-extended -regex "$1")
}
function get_image() { # select a image
PS3="Select OS to write the tf card: "
select OS in "${!SUPPORT_OS[@]}"; do
get_images "${SUPPORT_OS[$OS]}"
break
done
PS3="Select the image to write the tf card: "
select image in "${OS_IMAGES[@]}"; do
OS_IMAGE="$image"
break
done
}
function write_image() { # write the image to the tf card
echo "$1"
case "${1##*.}" in
"zip")
FILESIZE=$(unzip -l "$1" | awk '/\.img/ {print $1}')
# sudo unzip -p "$1" | pv --size "$FILESIZE" | dd of="$TF_CARD" bs=4M
;;
"xz")
FILESIZE=$(xz -v -l "$1" | awk 'match($0, /Uncompressed size:\s+[0-9,.]+\sMiB\s\(([0-9,]+)\sB\)/, m) {gsub(",", "", m[1])} {print m[1]}')
xzcat "$1" | pv --size "$(($FILESIZE / 1024 / 1024))M" | dd of="$TF_CARD" bs=4M
;;
"gz")
FILESIZE=$(gzip --list "$1" | awk 'FNR == 2 {print $2}')
gzip --decompress --keep --stdout "$1" | pv --size "$(($FILESIZE / 1024 / 1024))M" | dd of="$TF_CARD" bs=4M
;;
esac
}
# ------------------------------------------------------------------------------
# main
# ------------------------------------------------------------------------------
function main() {
get_tf_card
get_image
write_image "$OS_IMAGE"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment