Skip to content

Instantly share code, notes, and snippets.

@wsciaroni
Last active January 3, 2025 17:33
Show Gist options
  • Save wsciaroni/986fc5649573efb03194450a6191f571 to your computer and use it in GitHub Desktop.
Save wsciaroni/986fc5649573efb03194450a6191f571 to your computer and use it in GitHub Desktop.
This bash script automates the process of securely copying image files from an SD card to a date and time stamped location with optimized network throughput, checksum verification, and a progress bar.
#!/bin/bash
# Function to get the mount point of the SD card
get_sd_card_mount() {
local initial_mounts mounts_after_removal final_mounts added_mounts mount i sd_card_index
# Get initial list of mounts
readarray -t initial_mounts <<< "$(lsblk -o NAME,RM,MOUNTPOINT | grep '1' | awk '$3 != "" {print $3}')"
# Prompt user to remove the SD card
read -r -p "Please remove the SD card and press Enter..."
# Get the new list of mounts after removing the SD card
readarray -t mounts_after_removal <<< "$(lsblk -o NAME,RM,MOUNTPOINT | grep '1' | awk '$3 != "" {print $3}')"
# Prompt user to insert the SD card
read -r -p "Please insert the SD card and press Enter..."
# Get the final list of mounts after inserting the SD card
readarray -t final_mounts <<< "$(lsblk -o NAME,RM,MOUNTPOINT | grep '1' | awk '$3 != "" {print $3}')"
# Find the added mount point (the SD card)
added_mounts=()
for mount in "${final_mounts[@]}"; do
if [[ ! " ${mounts_after_removal[@]} " =~ " ${mount} " ]]; then
added_mounts+=("$mount")
fi
done
# Handle cases with multiple added mounts
if [[ ${#added_mounts[@]} -gt 1 ]]; then
echo "Multiple new mounts detected:"
for i in "${!added_mounts[@]}"; do
echo "$((i+1))) ${added_mounts[$i]}"
done
read -r -p "Select the SD card mount (1-${#added_mounts[@]}): " sd_card_index
if [[ ! "$sd_card_index" =~ ^[0-9]+$ ]] || (( sd_card_index < 1 || sd_card_index > ${#added_mounts[@]} )); then
echo "Invalid selection."
exit 1
fi
echo "${added_mounts[$((sd_card_index-1))]}"
elif [[ ${#added_mounts[@]} -eq 1 ]]; then
echo "${added_mounts[0]}"
else
echo "No new mount detected. Please make sure the SD card is inserted correctly."
exit 1
fi
}
# Function to display the progress bar
show_progress() {
local percent bar_length filled_length empty_length bar
percent=$(( (files_copied * 100) / total_files ))
bar_length=50
filled_length=$(( (percent * bar_length) / 100 ))
empty_length=$(( bar_length - filled_length ))
bar=$(printf "%${filled_length}s" '' | tr ' ' '#')$(printf "%${empty_length}s" '')
printf "\rProgress: [%s] %d%% (%d/%d)" "$bar" "$percent" "$files_copied" "$total_files"
}
# Function to copy files with checksum verification
copy_files_with_checksum() {
local source_file dest_file source_checksum dest_checksum
local checksum_file="$current_time/hash.md5"
touch "$checksum_file"
find "$selected_sd_card" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.JPG" -o -iname "*.PNG" -o -iname "*.orf" \) -print0 | while IFS= read -r -d '' source_file; do
cp "$source_file" "$current_time"
files_copied=$((files_copied + 1))
show_progress
# Calculate checksums
source_checksum=$(md5sum "$source_file" | awk '{print $1}')
local base_file_name=$(basename "$source_file")
dest_file="$current_time/$base_file_name"
dest_checksum=$(md5sum "$dest_file" | awk '{print $1}')
# Compare checksums and only print if mismatch
if [[ "$source_checksum" != "$dest_checksum" ]]; then
echo -e "\nChecksum mismatch: $source_file"
fi
# Append checksum to the checksum file
echo "$source_checksum $base_file_name" >> "$checksum_file"
done
}
# Main script execution
main() {
local current_time total_files files_copied selected_sd_card
# Create the directory path with year, month, day, and timestamp
current_time=$(date +%Y/%m/%d/%H%M%S)
mkdir -p "$current_time"
# Get the SD card mount point
selected_sd_card=$(get_sd_card_mount)
# Print the filepath of the SD card
echo "SD card detected at: $selected_sd_card"
# Get the total number of files to copy
total_files=$(find "$selected_sd_card" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.JPG" -o -iname "*.PNG" -o -iname "*.orf" \) | wc -l)
files_copied=0
# Copy the files with checksum verification
copy_files_with_checksum
printf "\n"
echo "Images copied to $current_time"
}
# Call the main function to start execution
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment