#!/bin/bash # Vorliegende sd.img Datei prüfen ob vorhanden und schreibbar [ ! -f "$1" -o ! -w "$1" ] && { echo "Usage: $0 imagefile"; exit 1; } # Mit kpartx den Inhalt von sd.img nach /dev/mapper als Partitionen darstellen lastpart="$(sudo kpartx -avs "$1" | awk 'match($0,/loop[0-9]+p[0-9]+/) {p=substr($0,RSTART,RLENGTH)}END{print p}')" # Die zu verkleinernde Partition liegt jetzt beispielsweise # als /dev/mapper/loop0p2 vor -> Variable lastpart # Falls das nicht geklappt hat -> Ende [ -n "$lastpart" ] || exit 1 # Nummer der letzten Partition ist der Teil hinter loop0p... lastpartno="${lastpart#loop*p}" # Nun können wir die letzte Partition verkleinern e2fsck -y -f /dev/mapper/"$lastpart" resize2fs -f -Mp /dev/mapper/"$lastpart"; rc="$?" # Bis hier ist alles relativ ungefährlich gewesen. # Herausfinden, wie groß das Dateisystem geworden ist (in Bytes), # und in der Variable lastsize speichern lastsize="$(dumpe2fs /dev/mapper/"$lastpart" 2>&1 | awk -F: '/Block count/{count=$2} /Block size/{size=$2} END{print count*size}')" # Jetzt können wir das Partitions-Mapping wieder aufheben, # damit ist die Image-Datei nicht mehr "in Benutzung" sudo kpartx -d "$1" # Falls zwischendrin etwas schief gegangen ist: Abbrechen [ "$rc" = 0 ] || exit 1 # Nun der gefährliche Teil. Wir tragen die neue Partitionsgröße # in die Partitionstabelle ein. start="$(sudo LC_ALL=C parted -s "$1" unit B print | awk '/^ *'"$lastpartno"' /{print $2}')"; start="${start%B}" let end="$start + $lastsize" echo "Letzte Partition start: $start, end: $end, size=$lastsize" echo 'Yes' | sudo LC_ALL=C parted ---pretend-input-tty "$1" resizepart "${lastpartno}" "${end}B" # Ende in Sektoren für dd. let end="$end / 512 + 1" # Den Rest der Datei wegschneiden. dd if=/dev/null of="$1" bs=512 seek="$end" # Fertig echo "Fertig." ls -ld "$1"