#!/bin/bash # maravento.com # ################################################################################ # # makemd5 - Create MD5 checksum files using zenity # # Nautilus Path: ~/.local/share/nautilus/scripts or ~/.config/nautilus/scripts # Caja Path: ~/.config/caja/scripts # Thunar Path: ~/.local/share/Thunar/scripts or ~/.config/Thunar/scripts # Nemo Path: ~/.local/share/nemo/scripts # ################################################################################ set -uo pipefail # check no-root if [ "$(id -u)" == "0" ]; then echo "[ERROR] This script should not be run as root." exit 1 fi echo "Start MakeMD5. Wait..." show_error() { zenity --error --title="Make MD5" --text="$1" exit 1 } show_info() { zenity --info --title="Make MD5" --text="$1" } if ! command -v zenity &> /dev/null; then echo "Error: zenity is required but not installed." exit 1 fi if ! command -v md5sum &> /dev/null; then show_error "Error: md5sum is required but not installed." fi files=() if [ -n "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS:-}" ]; then IFS=$'\n' read -d '' -r -a files <<< "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" elif [ -n "${THUNAR_SELECTION:-}" ]; then IFS=$'\n' read -d '' -r -a files <<< "$THUNAR_SELECTION" elif [ -n "${NEMO_SCRIPT_SELECTED_FILE_PATHS:-}" ]; then IFS=$'\n' read -d '' -r -a files <<< "$NEMO_SCRIPT_SELECTED_FILE_PATHS" elif [ "$#" -gt 0 ]; then files=("$@") else selection=$(zenity --file-selection \ --multiple \ --separator='|' \ --title="Select files to create checksums for") zenity_exit=$? [ "$zenity_exit" -ne 0 ] && exit 0 IFS='|' read -r -a files <<< "$selection" fi if [ "${#files[@]}" -eq 0 ]; then show_error "No files selected." fi for file in "${files[@]}"; do if [ ! -e "$file" ]; then show_error "'$file' does not exist." fi if [ -d "$file" ]; then show_error "'$file' is a directory.\nThis script only works with files." fi if [ ! -r "$file" ]; then show_error "Cannot read '$file'.\nCheck file permissions." fi done if [ "${#files[@]}" -eq 1 ]; then single_file="${files[0]}" default_name="$(basename "$single_file").md5" dialog_text="Creating checksum for: $(basename "$single_file")\n\nChecksum file name:" else default_name="checksums.md5" dialog_text="Creating checksums for ${#files[@]} files.\n\nChecksum file name:" fi choice=$(zenity --list \ --title="MD5 Checksum Generation" \ --text="$dialog_text" \ --radiolist \ --column="Select" \ --column="Option" \ --column="Description" \ TRUE "auto" "Use automatic naming: $default_name" \ FALSE "custom" "Choose custom name" \ --height=350 \ --width=800) case "$choice" in "auto") if [ "${#files[@]}" -eq 1 ]; then checksum_file="$(dirname "${files[0]}")/$default_name" else checksum_file="$(dirname "${files[0]}")/$default_name" fi ;; "custom") checksum_file=$(zenity --file-selection \ --save \ --confirm-overwrite \ --filename="$default_name" \ --title="Save MD5 checksum file as...") zenity_exit=$? [ "$zenity_exit" -ne 0 ] && exit 0 ;; *) exit 0 ;; esac if [ -z "$checksum_file" ]; then show_error "No checksum file name specified." fi if [ "$choice" = "auto" ] && [ -e "$checksum_file" ]; then if ! zenity --question \ --title="File Exists" \ --text="Checksum file already exists:\n$(basename "$checksum_file")\n\nDo you want to overwrite it?"; then show_info "Operation cancelled." exit 0 fi fi temp_dir=$(mktemp -d) manifest_file="$temp_dir/files.txt" trap 'rm -rf "$temp_dir"' EXIT checksum_dir=$(dirname "$checksum_file") for file in "${files[@]}"; do if [[ "$file" == "$checksum_dir"* ]]; then rel_path=$(realpath --relative-to="$checksum_dir" "$file") echo "$rel_path" >> "$manifest_file" else echo "$file" >> "$manifest_file" fi done ( echo "# Calculating MD5 checksums..." echo "10" total_files=${#files[@]} current=0 > "$checksum_file" while IFS= read -r file_path; do current=$((current + 1)) progress=$((10 + (current * 80 / total_files))) echo "$progress" echo "# Processing $(basename "$file_path") ($current/$total_files)..." if [[ "$file_path" == /* ]]; then actual_file="$file_path" else actual_file="$checksum_dir/$file_path" fi if hash=$(md5sum "$actual_file" 2>/dev/null); then checksum_only=$(echo "$hash" | awk '{print $1}') printf '%s %s\n' "$checksum_only" "$file_path" >> "$checksum_file" else echo "Error processing $file_path" >&2 exit 1 fi done < "$manifest_file" echo "100" echo "# Complete!" ) | zenity --progress \ --title="Creating MD5 Checksums" \ --text="Initializing..." \ --percentage=0 \ --auto-close progress_exit=$? if [ "$progress_exit" -eq 0 ] && [ -s "$checksum_file" ]; then file_count=$(wc -l < "$checksum_file") show_info "SUCCESS\n\nChecksum file created: $(basename "$checksum_file")\nFiles processed: $file_count\nLocation: $(dirname "$checksum_file")\n\nYou can now use this file to verify the integrity of your files." else show_error "FAILED\n\nUnable to create checksum file.\nCheck that you have write permissions in the target directory." fi