Once you read an image from as SD card, it'll be the full 4 or 8 G, which may be way more than the actual data storage size. This script, which you can download run as "script.sh pi.img" on the image will resize the binary file

#!/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 $3}' ) * 1024 )) # 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

you can re-expand on boot with 

sudo raspi-config --expand-rootfs

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

This page (Bonus! Shrinking Images) was last updated on Nov 27, 2021.

Text editor powered by tinymce.