Script for USB stick operations


Script for USB stick operations

One of the most common things to do on a computer, specially if you have SBCs like a Raspberry or other handheld devices is to format and backup USB sticks or SDCards. Instead of looking up for the commands all the time, i made this simple script to automate a bit things and also make the process more secure, as you cannot by mistake select one of your hard drives... don't ask...

The script will only list USB/removable drives, using the lsblk command and will guide you through fzf menus and questions. It also has a simple file selector thing, made with fzf to select an image to file. When started will ask you to select the drive/stick you want to make the operations.

diskselect

Currently it can Format, make an image backup with dd and also write an image file to the usb stick.

menu

At every step, will give you information on what is about to be done and give your consent, avoiding any surprises

question

In case you select to write an image to a usb drive, it will let you chose a file, through a fzf file selector, to avoid mistype a filename. Everything happens through menus.

selfile

For sure, it speeds things up and makes them more secure. I feel more comfortable formating a usb stick now, than have to use fdisk find the drive i want through a big list of drives and try not to mistype a letter, thus selecting my main disk drive... >:(

The script is as follows:

#!/bin/bash

#title           : usb stick operations
#description     : script to manage common usb stick operations
#author          : xqtr | http://cp737.net
#date            : 2024/10/28
#version         : 1.0
#usage           : 
#notes           : install fzf

script="${0##*/}"
script="${script%.*}"
DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

#yellow start 
    C14="\e[1;33m"
#blue start 
    C01="\e[0;34m"
#color end
    CE="\e[0m"
#red start
    C04="\e[1;31m"
#black start
    C00="\e[0;30m"
#dark gray start
    C08="\e[1;30m"
#light blue start
    C09="\e[1;34m"
#green start
    C02="\e[0;32m"
#light green start
    C10="\e[1;32m"
#cyan start
    C03="\e[0;36m"
#light cyan start
    C11="\e[1;36m"
#light red start
    C12="\e[0;31m"
#purple start
    C05="\e[0;35m"
#light purple start
    C13="\e[1;35m"
#brown start
    C06="\e[0;33m"
#light gray start
    C07="\e[0;37m"
#white 
    C15="\e[1;37m"
#setting frequent stings
    YNYES="("$C14"Y"$CE"/"$C14"n"$CE")("$C14"Enter"$CE"=yes)"
    YNNO="("$C14"y"$CE"/"$C14"N"$CE")("$C14"Enter"$CE"=no)"

function presskey() {
  echo ""
  echo "Press a key to continue..."
  read -n 1
}

prompt_confirm_no() {
  while true; do
    echo -e -n "${1:-Continue?} ${YNNO}: "
    read -e -r -n 1 REPLY
    case $REPLY in
      [yY]) echo ; return 0 ;;
      [nN]) echo; echo "Aborting..."; sleep 1; return 1 ;;
      $'\0A') echo; echo "Aborting..."; sleep 1; return 1 ;;
      *) printf " \033[31m %s \n\033[0m" "invalid input"
    esac 
  done  
}

function fzz() {
  #"right,50%,:wrap"
  fzf --ansi --bind 'enter:execute(echo {1})+abort' --bind 'end:last' --bind 'home:first' --header $'\x1b[1;32m'"$1"
}

function backup() {
  clear
  echo "You are going to create an image file of disk: $1"
  prompt_confirm_no || return 1
  echo "Unmounting USB stick..."
  sudo umount /dev/$1

  echo "Enter full absolute path/filename of image file:"
  read -p ":> " fn

  echo "Write /dev/$1 to file: $fn"
  prompt_confirm_no || return 1

  sudo dd if=/dev/$1 of="$fn" bs=1M status=progress

  echo "Finished. Check for errors..."  
}

function select_file() {
  while true 
do
  SELECTED="$(CLICOLOR_FORCE=1 ls -G -a --group-directories-first | fzf --header "Select File | Dir: $(pwd)")"
  if [ -z "$SELECTED" ]
  then
    exit 0
  fi

  if [ -d "$SELECTED" ]
  then
    cd $SELECTED
  else
    echo "$(pwd)/$SELECTED"
    return 0
  fi
done
}

function image() {
  clear
  echo "You are going to write an image file to disk: $1"
  prompt_confirm_no || return 1
  echo "Unmounting USB stick..."
  sudo umount /dev/$1

  fn=$(select_file)
  #read -p ":> " fn

  if [ -z "$fn" ]; then
    echo "Aborting..."
    sleep 1
    exit 1
  fi

  echo "Write $fn to device: /dev/$1"
  prompt_confirm_no || return 1

  sudo dd if="$fn" of=/dev/$1 bs=1M status=progress

  echo "Finished. Check for errors..."  
}

function format() {
  option=$(echo "1. FAT
2. EXT3
3. EXT4
4. VFAT
5. EXFAT
6. MSDOS
X. Exit" | fzz "Select Format Type | Disk: $1")

    if [ ! -z "$option" ]
      then
        echo "Unmounting USB stick... $1"
        sudo umount /dev/$1
        ch="$option"
        case $ch in
          1.*) sudo mkfs.fat /dev/$1;;
          2.*) sudo mkfs.ext3 /dev/$1;;
          3.*) sudo mkfs.ext4 /dev/$1;;
          4.*) sudo mkfs.vfat /dev/$1;;
          5.*) sudo mkfs.exfat /dev/$1;;
          6.*) sudo mkfs.msdos /dev/$1;;
          X.*) break;;
        esac
      echo "Checking for errors..."
      sudo fsck /dev/$1
    fi

}

disk=$(lsblk -o HOTPLUG,NAME,VENDOR,MODEL,SIZE | grep "^ *1" | sed "s/      //g" | cut -d" " -f2- | fzz "Select USB Stick" | cut -d" " -f 1)

if [ -z $disk ]; then
  echo "No USB stick selected."
  exit 1
fi

option=$(echo "1. Format
2. Backup to Image
3. Write Image to Device
X. Exit" | fzz "Select Operation")

    if [ ! -z "$option" ]
      then
        ch="$option"
        case $ch in
          1.*) format $disk;;
          2.*) backup $disk;;
          3.*) image $disk;;
          X.*) exit 1;;
        esac
    fi

Add a comment

Previous Next