0 of 10 steps0%
Back to guides
Tech & ComputersMedium

How to Modify Hard Drives in Linux — USBs, External Drives, Everything

Direct, hands-on reference for managing block devices in Linux. lsblk, fdisk, mkfs, mount, fstab, dd, LUKS, LVM, recovery. Rule #0: identify the right device first. No filler, no fluff — just the commands.

admin
15 min
10 steps
9 views

See what's attached

Step 1 of 10

  • *Rule #0:** identify the right device first. Pointing `mkfs` at the wrong drive wipes it.
  • ```bash
  • lsblk # tree view of disks + partitions + mount points
  • lsblk -f # + filesystem, label, UUID
  • lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,LABEL,UUID
  • fdisk -l # raw partition table dump
  • parted -l # modern; works with GPT too
  • blkid # UUIDs + types of all block devices
  • df -h # mounted filesystems with usage
  • df -hT # + filesystem type
  • mount | column -t # what's mounted and how
  • cat /proc/partitions # kernel's view
  • ls -la /dev/disk/by-uuid/ # UUID symlinks
  • ls -la /dev/disk/by-label/ # label symlinks (if set)
  • ```
  • *Names you'll see:**
  • | Pattern | Meaning |
  • |---------|---------|
  • | `/dev/sda`, `/dev/sdb` | First/second SATA/SCSI/USB disk (whole disk) |
  • | `/dev/sda1`, `/dev/sda2` | First/second partition on sda |
  • | `/dev/nvme0n1` | First NVMe drive (whole) |
  • | `/dev/nvme0n1p1` | First partition on NVMe drive |
  • | `/dev/mmcblk0` | SD card |
  • | `/dev/loop0` | Loop device (a file pretending to be a disk) |
  • USB drives show up as `/dev/sd*` on most systems. External NVMe in a USB enclosure is `/dev/sd*` too.

Drive info & health

Step 2 of 10

  • ```bash
  • # SMART health (needs smartmontools)
  • sudo apt install smartmontools
  • sudo smartctl -H /dev/sda # quick health check
  • sudo smartctl -a /dev/sda # full dump
  • sudo smartctl -t long /dev/sda # start extended self-test
  • sudo smartctl -l selftest /dev/sda # see test history
  • # Read/write speed
  • sudo hdparm -Tt /dev/sda # cached + buffered reads
  • sudo hdparm -I /dev/sda # drive identity + capabilities
  • # What's using an IO device right now
  • sudo iotop # per-process IO
  • sudo iostat -xz 1 # per-device IO stats
  • sudo lsof /dev/sda1 # which processes have files open on it
  • # UUID and serial
  • sudo blkid /dev/sda1
  • sudo hdparm -I /dev/sda | grep -i serial
  • ```
  • A `SMART overall-health self-assessment test result: PASSED` means the drive is probably fine. `FAILED!` means back up now and replace.

Partitioning

Step 3 of 10

  • *Two tools:**
  • | Tool | Use for |
  • |------|---------|
  • | `fdisk` | MBR partition tables. ≤ 2 TiB disks. Old but works. |
  • | `gdisk` | GPT partition tables. > 2 TiB. Modern default. |
  • | `parted` | Both. Better for scripting (non-interactive). |
  • ```bash
  • # Interactive — gdisk is recommended for new disks
  • sudo gdisk /dev/sdb
  • # n → new partition
  • # → partition number (default 1)
  • # → first sector (default)
  • # → last sector (default = whole disk, or specify like +32G)
  • # → type code (8300 = Linux, 8200 = swap, 0700 = NTFS/exFAT, ef00 = EFI)
  • # w → write and quit
  • # q → quit without writing
  • # One-shot with parted (scriptable)
  • sudo parted /dev/sdb mklabel gpt
  • sudo parted /dev/sdb mkpart primary ext4 0% 100%
  • sudo parted /dev/sdb set 1 boot on # if it's an EFI System Partition
  • sudo parted /dev/sdb print # verify
  • ```
  • *Partition type codes (gdisk):**
  • | Code | Meaning |
  • |------|---------|
  • | 0700 | Microsoft basic data (NTFS, exFAT) |
  • | 8200 | Linux swap |
  • | 8300 | Linux filesystem |
  • | 8304 | x86-64 root (for LUKS-encrypted root) |
  • | 8E00 | Linux LVM |
  • | EF00 | EFI System Partition |
  • | FD00 | Linux RAID |

Formatting (making a filesystem)

Step 4 of 10

  • ```bash
  • # Pick the right mkfs:
  • sudo mkfs.ext4 -L "MyDrive" /dev/sdb1 # Linux default; -L sets label
  • sudo mkfs.ext4 -L "MyDrive" -U random /dev/sdb1 # -U sets UUID explicitly
  • sudo mkfs.vfat -n "USBSTICK" /dev/sdb1 # FAT32; -n is the label (11 chars)
  • sudo mkfs.exfat -n "BIGUSB" /dev/sdb1 # exFAT (≥4GB files; needs exfatprogs)
  • sudo mkfs.ntfs -F -L "WinDrive" /dev/sdb1 # NTFS (needs ntfs-3g)
  • sudo mkfs.btrfs -L "BTRFS" /dev/sdb1 # btrfs
  • sudo mkfs.xfs -L "XFS" /dev/sdb1 # XFS
  • # Swap
  • sudo mkswap -L "SWAP" /dev/sdb1
  • sudo swapon /dev/sdb1
  • sudo swapoff /dev/sdb1
  • ```
  • *Choose by use case:**
  • | Use | Format | Why |
  • |-----|--------|-----|
  • | Linux boot/system | ext4 | Default, well-supported, journaling |
  • | Big Linux storage, snapshots | btrfs / xfs | Modern features |
  • | USB stick for sharing | vfat (FAT32) | Works everywhere; max file 4 GiB |
  • | Big USB stick for sharing | exfat | Cross-OS, no 4 GiB limit |
  • | Windows drive | ntfs | Native Windows format |
  • | External SSD for Windows+Mac | exfat | Cross-platform without drivers |
  • *Don't:** format a disk with `dd if=/dev/zero` and then call it done. That's a wipe, not a filesystem.

Mounting

Step 5 of 10

  • ```bash
  • # One-shot
  • sudo mkdir -p /mnt/usb
  • sudo mount /dev/sdb1 /mnt/usb
  • ls /mnt/usb
  • sudo umount /mnt/usb # unmount (not "unmount"; no 'n')
  • # By label (works even if the device name changes)
  • sudo mount LABEL="MyDrive" /mnt/usb
  • # By UUID (the most reliable identifier)
  • sudo mount UUID="abcd-1234-..." /mnt/usb
  • # Mount options you actually want
  • sudo mount -o rw,noatime,uid=1000,gid=1000 /dev/sdb1 /mnt/usb
  • # rw → read-write
  • # ro → read-only (safer for recovery)
  • # noatime → don't update access time (less SSD wear)
  • # noexec → prevent running binaries (safer for USB sticks)
  • # nosuid → ignore setuid bits (safer for USB sticks)
  • # uid/gid → make a vfat/exfat mount owned by your user
  • # Re-read /etc/fstab without rebooting
  • sudo mount -a
  • ```
  • *Always unmount before unplugging a USB stick:**
  • ```bash
  • sync
  • sudo umount /mnt/usb
  • ```
  • If `umount` says "target is busy":
  • ```bash
  • sudo lsof +D /mnt/usb # list open files
  • sudo fuser -mv /mnt/usb # show PIDs
  • # kill or close those processes, then umount
  • ```
  • *Lazy unmount** (detach now, clean up when free):
  • ```bash
  • sudo umount -l /mnt/usb
  • ```

/etc/fstab (persistent mounts)

Step 6 of 10

  • Format:
  • ```
  • <device> <mountpoint> <fstype> <options> <dump> <fsck-order>
  • ```
  • ```bash
  • # Generate a line from your mounted USB to paste into /etc/fstab
  • # (use UUID, never /dev/sdX, since the device letter can change)
  • UUID=$(sudo blkid -s UUID -o value /dev/sdb1)
  • echo "UUID=$UUID /mnt/usb ext4 defaults,noatime,noexec,nosuid 0 2"
  • # Then:
  • sudo cp /etc/fstab /etc/fstab.bak.$(date +%s)
  • sudo \$EDITOR /etc/fstab # paste the line
  • sudo mount -a # test; pulls and remounts everything
  • ```
  • *Fields explained:**
  • | Field | Meaning |
  • |-------|---------|
  • | device | `UUID=…` or `LABEL=…` (not `/dev/sdX`!) |
  • | mountpoint | Where it shows up in the filesystem tree |
  • | fstype | `ext4`, `vfat`, `ntfs`, `btrfs`, `xfs`, `auto` |
  • | options | `defaults` = `rw,suid,dev,exec,auto,nouser,async` |
  • | dump | `0` = skip for backups (almost always 0) |
  • | fsck-order | `0` = skip fsck, `1` = root, `2` = other. ext4 uses 2. |
  • A broken /etc/fstab line can prevent the system from booting. Always back it up first (`cp /etc/fstab /etc/fstab.bak`).

USB boot drives

Step 7 of 10

  • ```bash
  • # Find your USB
  • lsblk # e.g. /dev/sdc, 8 GiB stick
  • USB=/dev/sdc
  • # Wipe + write ISO directly (fastest)
  • sudo dd if=ubuntu-24.04-desktop-amd64.iso of=\$USB bs=4M status=progress oflag=sync
  • # bs=4M → write 4 MiB at a time (fast)
  • # status=progress → show progress
  • # oflag=sync → flush each block (safer; slightly slower)
  • # Safer: also verify
  • sudo sync
  • sudo cmp -n \$(stat -c%s ubuntu-24.04-desktop-amd64.iso) ubuntu-24.04-desktop-amd64.iso \$USB
  • # Reports "differ at byte X" or completes silently = match
  • # Ventoy (write once, then drop multiple ISOs onto the stick)
  • # 1. Download ventoy, write the bootloader: sudo ./Ventoy2Disk.sh -i /dev/sdc
  • # 2. Mount the stick, copy ISOs to it. Boot menu picks which one.
  • ```
  • Ventoy is the right answer if you carry multiple ISOs on one stick. Otherwise just `dd` the ISO.

Imaging, cloning, wiping

Step 8 of 10

  • *Clone a drive to another drive (byte-for-byte):**
  • ```bash
  • sudo dd if=/dev/sda of=/dev/sdb bs=4M status=progress oflag=sync
  • # both must be unmounted first
  • ```
  • *Make a disk image file:**
  • ```bash
  • sudo dd if=/dev/sda of=disk.img bs=4M status=progress oflag=sync
  • sudo sync
  • ls -lh disk.img
  • ```
  • *Restore an image:**
  • ```bash
  • sudo dd if=disk.img of=/dev/sda bs=4M status=progress oflag=sync
  • ```
  • *Compressed image:**
  • ```bash
  • # Save
  • sudo dd if=/dev/sda bs=4M status=progress | gzip -c > disk.img.gz
  • # Restore
  • gunzip -c disk.img.gz | sudo dd of=/dev/sdb bs=4M status=progress oflag=sync
  • # or via pv (shows progress):
  • sudo pv /dev/sda | gzip > disk.img.gz
  • ```
  • *Recover a failing drive (use ddrescue, NOT dd):**
  • ```bash
  • sudo apt install gddrescue
  • sudo ddrescue /dev/sda disk.img rescue.log # first pass: skip bad areas
  • sudo ddrescue -d -r3 /dev/sda disk.img rescue.log # second pass: retry bad
  • ```
  • *Secure wipe:**
  • ```bash
  • # SSD: use the drive's built-in secure erase (fast, works through wear-leveling)
  • sudo hdparm --user-master u --security-set-pass p /dev/sda
  • sudo hdparm --user-master u --security-erase p /dev/sda
  • # HDD: zero out
  • sudo dd if=/dev/zero of=/dev/sda bs=4M status=progress oflag=sync
  • # For very paranoid wiping of HDD (multi-pass):
  • sudo shred -v -n 3 -z /dev/sda
  • # -n 3 → 3 random passes
  • # -z → final zero pass
  • ```

Filesystem maintenance

Step 9 of 10

  • ```bash
  • # ext4: check filesystem (must be unmounted)
  • sudo umount /dev/sdb1
  • sudo fsck.ext4 -f /dev/sdb1 # -f forces check even if clean
  • sudo e2fsck -f /dev/sdb1 # same tool
  • # ext4: resize filesystem after partition resize
  • sudo resize2fs /dev/sdb1 # grow to fill partition
  • sudo resize2fs /dev/sdb1 20G # shrink to 20G (partition must be ≥ this size first)
  • # btrfs
  • sudo btrfs filesystem balance /mnt/data
  • sudo btrfs scrub start /mnt/data # check+repair RAID
  • sudo btrfs device add /dev/sdc1 /mnt/data # add a device
  • # xfs
  • sudo xfs_repair /dev/sdb1 # unmount first
  • sudo xfs_growfs /mnt/data # grow to fill larger partition
  • # swap
  • sudo swapoff /dev/sdb1
  • sudo mkswap /dev/sdb1 # recreate (destroys contents)
  • sudo swapon /dev/sdb1
  • # Change label without reformatting
  • sudo e2label /dev/sdb1 "NewLabel" # ext2/3/4
  • sudo ntfslabel /dev/sdb1 "NewLabel" # ntfs (needs ntfs-3g)
  • sudo fatlabel /dev/sdb1 "NEWLABEL" # vfat
  • sudo btrfs filesystem label /dev/sdb1 "NewLabel"
  • sudo xfs_admin -L "NewLabel" /dev/sdb1 # xfs
  • ```
  • `resize2fs` for ext4 can grow online (mounted) but only shrinks offline. Plan partition sizes ahead.

Cheat sheet (copy/paste)

Step 10 of 10

  • ```bash
  • # What's here
  • lsblk -f
  • # Make a USB stick bootable from an ISO
  • USB=/dev/sdc && sudo dd if=path/to/iso of=\$USB bs=4M status=progress oflag=sync && sync
  • # Wipe + partition + format + mount an external drive (DESTRUCTIVE)
  • DRIVE=/dev/sdb
  • sudo umount \${DRIVE}* 2>/dev/null
  • sudo dd if=/dev/zero of=\$DRIVE bs=1M count=10 # wipe old partition table
  • sudo parted \$DRIVE mklabel gpt
  • sudo parted \$DRIVE mkpart primary ext4 0% 100%
  • sudo mkfs.ext4 -L "External" \${DRIVE}1
  • sudo mkdir -p /mnt/ext && sudo mount \${DRIVE}1 /mnt/ext
  • # Add to /etc/fstab
  • echo "UUID=\$(sudo blkid -s UUID -o value \${DRIVE}1) /mnt/ext ext4 defaults,noatime 0 2" | sudo tee -a /etc/fstab
  • # Check disk health
  • sudo smartctl -H /dev/sda
  • ```
  • That's the loop. **Identify → plan → partition → format → mount → persist in fstab.** Reverse the steps to clean up.