Once you create an image from an SD card, the resulting file is always the full capacity of the card, which may be way more than the actual data storage size. Copy the script below and paste it in a new file…suppose it’s called script.sh…which can then be executed as follows to shrink the image file to a more manageable size:

sudo bash ./script.sh pi.img

The script:

#!/bin/env bash

IMG="$1"

if [[ -e $IMG ]]; then
  P_START=$( fdisk -lu $IMG | grep Linux | awk '{print $2}' ) # Start of 2nd partition in 512 byte sectors
  P_SIZE=$(( $( fdisk -lu $IMG | grep Linux | awk '{print $4}' ) * 512 )) # Partition size in bytes
  losetup /dev/loop2 $IMG -o $(($P_START * 512)) --sizelimit $P_SIZE
  fsck -f /dev/loop2
  resize2fs -M /dev/loop2 # Make the filesystem as small as possible
  fsck -f /dev/loop2
  P_NEWSIZE=$( dumpe2fs /dev/loop2 2>/dev/null | grep '^Block count:' | awk '{print $3}' ) # In 4k blocks
  P_NEWEND=$(( $P_START + ($P_NEWSIZE * 8) - 1 )) # in 512 byte sectors
  losetup -d /dev/loop2
  echo -e "p\nd\n2\nn\np\n2\n$P_START\n$P_NEWEND\np\nw\n" | fdisk $IMG
  I_SIZE=$((($P_NEWEND + 1) * 512)) # New image size in bytes
  truncate -s $I_SIZE $IMG
else
  echo "Usage: $0 filename"
fi

After writing this image to a card and booting from it, the filesystem can be re-expanded to the full card using:

sudo raspi-config --expand-rootfs

This guide was first published on May 30, 2016. It was last updated on Mar 08, 2024.

This page (Bonus! Shrinking Images) was last updated on Mar 08, 2024.

Text editor powered by tinymce.