基于Raspbian系统的SD卡自动克隆Shell脚本开发需求
Alright, let's tackle this two-part problem: creating a shell script to clone your OS from a USB drive (/dev/sda) to an SD card (/dev/sdb), and setting up automatic detection to trigger the script when the SD card is plugged in. Let's break this down step by step.
First, let's build a robust script that handles the cloning safely. Critical note: Double-check that /dev/sda is truly your source USB drive and /dev/sdb is the target SD card—mixing these up will erase data irreversibly. Use lsblk or fdisk -l to verify device paths before proceeding.
Here's the script (save it as /usr/local/bin/os-clone.sh):
#!/bin/bash # Ensure we're running as root (required for block device operations) if [ "$(id -u)" -ne 0 ]; then echo "This script needs root privileges. Run with sudo." exit 1 fi # Define source and target devices SOURCE="/dev/sda" TARGET="/dev/sdb" # Check if both devices exist if [ ! -b "$SOURCE" ]; then echo "Error: Source device $SOURCE doesn't exist." exit 1 fi if [ ! -b "$TARGET" ]; then echo "Error: Target device $TARGET doesn't exist." exit 1 fi # Unmount any mounted partitions on the target to avoid conflicts umount "${TARGET}?"* 2>/dev/null # Handle user confirmation (adjust this based on your environment: GUI or CLI) # Option 1: GUI confirmation (requires zenity) if command -v zenity &> /dev/null; then if ! zenity --question --width=500 --text="⚠️ WARNING: This will OVERWRITE ALL data on $TARGET with the contents of $SOURCE.\n\nPlease confirm:\n- $SOURCE is your source USB drive\n- $TARGET is your target SD card\n\nDo you want to start cloning?"; then echo "Clone aborted by user." exit 0 fi # Option 2: CLI confirmation (launches a terminal since udev runs in the background) else xterm -e "bash -c 'echo \"⚠️ WARNING: This will OVERWRITE ALL data on $TARGET with the contents of $SOURCE.\"; echo \"\"; echo \"Confirm $SOURCE = USB drive, $TARGET = SD card.\"; read -p \"Type YES to proceed, anything else to abort: \" CONFIRM; if [ \"\$CONFIRM\" = \"YES\" ]; then dd if=\"$SOURCE\" of=\"$TARGET\" bs=4M status=progress conv=fsync; else echo \"Aborted.\"; fi; read -p \"Press Enter to close this window.\"'" exit 0 fi # Start cloning with dd (bs=4M speeds up the process; status=progress shows real-time updates) echo "Starting clone from $SOURCE to $TARGET..." dd if="$SOURCE" of="$TARGET" bs=4M status=progress conv=fsync # Verify success if [ $? -eq 0 ]; then echo "✅ Clone completed successfully!" zenity --info --text="Clone finished successfully! You can safely remove the SD card." else echo "❌ Clone failed. Check device connections and try again." zenity --error --text="Clone failed! Please check device connections and try again." exit 1 fi
Make the script executable:
sudo chmod +x /usr/local/bin/os-clone.sh
Key Script Features:
- Root privilege check to ensure we can modify block devices
- Device existence validation to avoid targeting non-existent hardware
- Automatic unmounting of target partitions to prevent write conflicts
- Dual confirmation options (GUI with
zenityor CLI terminal) for different environments - Real-time progress tracking with
dd - Clear success/failure notifications
To trigger the script when the SD card is inserted, we'll use udev—Linux's built-in system for managing device events. Here's how to set it up:
Identify your SD card's udev properties
Plug in your SD card, then run this command to get its unique attributes:udevadm info --query=property --name=/dev/sdbLook for properties that uniquely identify SD cards, like
ID_BUS=mmc(most SD cards use the MMC bus, unlike USB drives which useID_BUS=usb).Create a udev rule
Create a new rule file at/etc/udev/rules.d/99-sd-card-clone.rules(the number ensures it runs after default system rules):# Trigger OS clone script when an SD card is inserted ACTION=="add", KERNEL=="sd[b-z]", SUBSYSTEM=="block", ENV{ID_BUS}=="mmc", RUN+="/usr/local/bin/os-clone.sh"ACTION=="add": Triggers when the device is first plugged inKERNEL=="sd[b-z]": Matches block devices sdb to sdz (avoids accidentally targeting the source USB drive/dev/sda)ENV{ID_BUS}=="mmc": Ensures only SD cards (not other USB devices) trigger the scriptRUN+="/usr/local/bin/os-clone.sh": Executes our cloning script
Reload udev rules
Apply the new rule without rebooting:sudo udevadm control --reload-rules sudo udevadm trigger
Important Notes for udev:
- udev runs scripts in a minimal background environment, so direct interactive commands (like
read) won't work. This is why our script useszenityor launches a terminal for user confirmation. - The rule targets the main block device (
sdb) instead of its partitions (sdb1,sdb2) to prevent multiple trigger events when the card is inserted. - Test the setup by unplugging and reinserting your SD card—you should see the confirmation prompt pop up automatically.
内容的提问来源于stack exchange,提问作者Jan B

