Last active
January 3, 2025 17:33
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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