PiShrink verkleinert Raspberry Pi-Images

Avatar von Christoph Langner

8 Min. Lesezeit

265 Aufrufe

Im Artikel SD-Karte eines Raspberry Pi als Image klonen, sichern und zurückspielen hatte ich bereits beschrieben, wie man eine RasPi-Installation von der Speicherkarte sichert und wiederherstellt – no shit, Sherlock. Eine Frage tauchte dabei jedoch des Öfteren auf: Die Image-Datei wird genauso groß wie die Speicherkarte, selbst wenn darauf noch viel Platz frei ist. Der…

Im Artikel SD-Karte eines Raspberry Pi als Image klonen, sichern und zurückspielen hatte ich bereits beschrieben, wie man eine RasPi-Installation von der Speicherkarte sichert und wiederherstellt – no shit, Sherlock. Eine Frage tauchte dabei jedoch des Öfteren auf: Die Image-Datei wird genauso groß wie die Speicherkarte, selbst wenn darauf noch viel Platz frei ist. Der „leere“ Bereich wird quasi mit ins Image gepackt. Dadurch muss die neue Speicherkarte mindestens genauso groß sein wie die alte. Zudem belegt ein für die spätere Archivierung bestimmtes Image viel Speicherplatz. Wie also lässt sich die Luft aus einem Raspberry-Pi-Image herauslassen?

Auf GitHub bin ich neulich über das Skript PiShrink gestolpert, das genau diese Aufgabe übernimmt. Das kleine Programm schnappt sich ein RasPi-Image, reduziert die Partitionsgröße auf das notwendige Minimum und integriert zudem ein Skript ins archivierte System, das beim nächsten Start auf echter Hardware die Partition automatisch auf den maximal verfügbaren Speicherplatz ausdehnt. So lässt sich das Image eines Raspbian-Systems von mehreren Gigabyte schnell auf ein paar Hundert Megabyte verkleinern – ganz ohne großen Aufwand. Auch beim Zurückspielen spart man Zeit, da sich das Dateisystem beim ersten Start des Raspberry Pi automatisch wieder auf die volle Größe erweitert.

$ mkdir ~/bin
$ wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh -P ~/bin
$ chmod +x ~/bin/pishrink.sh

Da es sich bei PiShrink um ein einfaches Bash-Skript handelt, ist die Installation des Programms nicht sonderlich kompliziert: Man muss das Skript lediglich aus dem Netz herunterladen und die Ausführungsrechte entsprechend setzen. Ich persönlich lege solche Skripte im Verzeichnis ~/bin im Home-Verzeichnis ab. Das System sollte diesen Ordner automatisch in den $PATH eures Benutzers aufnehmen, sodass man das Kommando ohne Pfadangabe von überall im System ausführen kann. Sollte das bei euch nicht der Fall sein, finden sich im Netz zahlreiche Anleitungen zum Erweitern der Umgebungsvariablen (der verlinkte Artikel bezieht sich auf Ubuntu, das Vorgehen ist bei anderen Distributionen jedoch sehr ähnlich).

PiShrink komprimiert Raspberry-Pi-Images

Nun solltet ihr das PiShrink-Skript mit einem beherzten pishrink.sh direkt im Terminal aufrufen können. Ohne die Angabe eines Images zeigt das Skript lediglich seine Syntax an. Im Endeffekt beschränkt sich der Aufruf auf die Angabe einer Image-Datei und optional eines zweiten Dateinamens, falls PiShrink das Original-Image des Raspberry Pi unangetastet lassen soll. Gibt man nur einen Dateinamen an, bearbeitet PiShrink das genannte Image direkt.

Der einzige Schalter -s ist dann wichtig, wenn man das Image eines RasPi-Systems verkleinern möchte, das nicht auf Raspbian basiert – also beispielsweise die Kodi-Distributionen LibreELEC oder OpenELEC. Genauer gesagt weist der Schalter PiShrink an, das automatische Ausdehnen des Systems beim nächsten Start zu unterlassen. Dazu trägt PiShrink normalerweise ein Kommando in die Datei /etc/rc.local ein, die unter Raspbian beim Booten automatisch ausgeführt wird. Diese Datei existiert jedoch bei LibreELEC (und einigen anderen Distributionen) nicht.

### Hilfe zu PiShrink aufrufen:
$ pishrink.sh
Usage: /home/toff/bin/pishrink.sh [-s] imagefile.img [newimagefile.img]
### Vorhandenes RasPi-Image verkleinern:
$ sudo pishrink.sh raspberry-pi.img
### Image verkleinern und Original behalten:
$ sudo pishrink.sh raspberry-pi.img raspberry-pi_pishrink.img
### Automatisches Vergrößern der Partition deaktivieren:
$ sudo pishrink.sh -s raspberry-pi.img raspberry-pi_klein.img

Wie kommt das nun alles zusammen? Als Beispiel verwende ich hier eine aktuelle Installation von Raspbian Lite auf einer 16 GByte großen SD-Karte. Diese legt man in den Kartenleser ein, ermittelt mit lsblk die Geräte-ID und sichert anschließend mit dd das Image auf die Festplatte. Die Image-Datei liegt danach unter dem Namen raspberry-pi.img rund 16 GByte groß auf der Festplatte – obwohl das Image eigentlich größtenteils leer ist. Außer dem Raspbian-System und ein paar Konfigurationen befinden sich keine weiteren Daten auf dem System.

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
[...]
sdd      8:48   1  14,9G  0 disk 
├─sdd1   8:49   1    63M  0 part /run/media/[...]/boot
└─sdd2   8:50   1  14,8G  0 part /run/media/[...]/0aed834e-8c8f-412d-a276-a26
$ sudo dd if=/dev/sdd of=~/raspberry-pi.img
15894831104 Bytes (16 GB, 15 GiB) kopiert, 210 s, 75,7 MB/s     
31116288+0 Datensätze ein
31116288+0 Datensätze aus
15931539456 Bytes (16 GB, 15 GiB) kopiert, 210,459 s, 75,7 MB/s
$ ls -alh ~/raspberry-pi.img 
-rw-r--r-- 1 root root 15G 24. Feb 21:48 raspberry-pi.img

Anschließend ruft man PiShrink entsprechend auf – da es sich um ein Raspbian-System handelt, lasse ich die Option -s weg. PiShrink kopiert zunächst das Image (achtet daher darauf, dass ausreichend freier Speicherplatz vorhanden ist), mountet die Kopie in ein temporäres Verzeichnis unter /tmp und reduziert anschließend die Größe des Images: von ursprünglich knapp 16 GByte auf nur noch etwa 1,6 GByte. Der erzielte Effekt hängt natürlich davon ab, wie viele echte Daten auf der SD-Karte des Raspberry Pi gespeichert waren.

$ sudo pishrink.sh raspberry-pi.img raspberry-pi_pishrink.img
Copying raspberry-pi.img to raspberry-pi_pishrink.img...
Creating new /etc/rc.local
e2fsck 1.43.4 (31-Jan-2017)
Durchgang 1: Inodes, Blöcke und Größen werden geprüft
Durchgang 2: Verzeichnisstruktur wird geprüft
Durchgang 3: Verzeichnisverknüpfungen werden geprüft
Durchgang 4: Referenzzähler werden überprüft
Durchgang 5: Zusammengefasste Gruppeninformation wird geprüft
/dev/loop2: 35832/959616 Dateien (0.2% nicht zusammenhängend), 321790/3872384 Blöcke
resize2fs 1.43.4 (31-Jan-2017)
resize2fs 1.43.4 (31-Jan-2017)
Die Größe des Dateisystems auf /dev/loop2 wird auf 382429 (4k) Blöcke geändert.
Start von Durchgang 2 (max = 40814)
Blöcke werden verschoben     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 3 (max = 119)
Die Inode-Tabelle wird gelesenXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 4 (max = 3178)
Die Inode-Referenzen werden aktualisierXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-
Das Dateisystem auf /dev/loop2 ist nun 382429 (4k) Blöcke lang.

Shrunk raspberry-pi_pishrink.img from 15G to 1,6G
$ ls -alh raspberry-pi*
-rw-r--r-- 1 root root  15G 27. Feb 11:08 raspberry-pi.img
-rw-r--r-- 1 root root 1,6G 27. Feb 11:30 raspberry-pi_pishrink.img

Geschrumpftes RasPi-Image wiederherstellen

Zum Test soll das ursprünglich auf einer 16-GByte-SD-Karte installierte Raspbian-System auf eine MicroSD-Karte mit nur 8 GByte umziehen. Dazu schreibe ich das mit PiShrink verkleinerte Image wieder mit dd auf die neue Karte, setze sie in den Raspberry Pi ein und starte das geschrumpfte System. Um den verfügbaren Speicherplatz vollständig zu nutzen, führt das System beim ersten Bootvorgang automatisch einen Neustart durch. Anschließend landet man im gewohnten Raspbian-System – ein df -h zeigt, dass das System jetzt die gesamte SD-Karte verwendet.

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
[...]
sdd      8:48   1   7,4G  0 disk 
├─sdd1   8:49   1    63M  0 part /run/media/[...]/boot
└─sdd2   8:50   1   7,3G  0 part /run/media/[...]/0aed834e-8c8f-412d-a276-a26
$ sudo dd if=raspberry-pi_pishrink.img of=/dev/sdd bs=1M; sync
1560+1 Datensätze ein
1560+1 Datensätze aus
1636684288 Bytes (1,6 GB, 1,5 GiB) kopiert, 116,203 s, 14,1 MB/s
pi@raspberrypi:~ $ df -h
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/root       7,2G    990M  6,0G   14% /
devtmpfs        459M       0  459M    0% /dev
tmpfs           463M       0  463M    0% /dev/shm
tmpfs           463M    6,2M  457M    2% /run
tmpfs           5,0M    4,0K  5,0M    1% /run/lock
tmpfs           463M       0  463M    0% /sys/fs/cgroup
/dev/mmcblk0p1   63M     21M   42M   33% /boot

Sichert man ein Raspberry-Pi-System, das nicht auf Raspbian basiert und keine /etc/rc.local enthält – wie etwa die bereits erwähnten Kodi-Distributionen LibreELEC oder OpenELEC – erscheinen beim Schrumpfen mit PiShrink Fehlermeldungen. Der Grund: PiShrink versucht standardmäßig, ein Kommando zur späteren automatischen Vergrößerung der Partition in diese Datei einzutragen. Um das zu vermeiden, muss beim Aufruf die Option -s verwendet werden. Damit lässt sich das Image auch ohne rc.local erfolgreich verkleinern.

### Fehlermeldungen beim Schrumpfen eines LibreELEC-Images:
$ sudo pishrink.sh libreelec.img
[...]
md5sum: /tmp/tmp.4ornQ3Va4y/etc/rc.local: Datei oder Verzeichnis nicht gefunden
/home/[...]/bin/pishrink.sh: Zeile 63: [: !=: Einstelliger (unärer) Operator erwartet.
[...]
### LibreELEC, OpenELEC und Co. schrumpft man besser so:
$ sudo pishrink.sh -s libreelec.img
Skipping autoexpanding process...
e2fsck 1.43.4 (31-Jan-2017)
/dev/loop2: Journal wird wiederhergestellt
Durchgang 1: Inodes, Blöcke und Größen werden geprüft
Durchgang 2: Verzeichnisstruktur wird geprüft
Durchgang 3: Verzeichnisverknüpfungen werden geprüft
Durchgang 4: Referenzzähler werden überprüft
Durchgang 5: Zusammengefasste Gruppeninformation wird geprüft
/dev/loop2: 861/1810432 Dateien (1.0% nicht zusammenhängend), 252448/7235584 Blöcke
resize2fs 1.43.4 (31-Jan-2017)
resize2fs 1.43.4 (31-Jan-2017)
Die Größe des Dateisystems auf /dev/loop2 wird auf 49976 (1k) Blöcke geändert.
Start von Durchgang 2 (max = 15759)
Blöcke werden verschoben     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 3 (max = 884)
Die Inode-Tabelle wird gelesenXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Start von Durchgang 4 (max = 143)
Die Inode-Referenzen werden aktualisiertXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-
Das Dateisystem auf /dev/loop2 ist nun 49976 (1k) Blöcke lang.

Shrunk libreelec.img from 7,5G to 563M

Das zurückgeschriebene System vergrößert sich anschließend jedoch nicht automatisch, da LibreELEC (und nach aktuellem Kenntnisstand auch OpenELEC) in seinen Menüs keine Option bietet, die Datenpartition manuell auf die volle Kartengröße auszudehnen. Die interne Routine zur Größenanpassung greift nur bei einer frisch kopierten Erstinstallation, wie im Skript ersichtlich. Um die Partition dennoch vollständig zu nutzen, hilft nur manuelles Nacharbeiten mit einem Partitionswerkzeug wie GParted. Unter Linux ist GParted direkt verfügbar, Windows-Nutzer können das Tool über eine Live-CD oder einen Live-USB-Stick verwenden.

Ähnliche Beiträge

11 Kommentare zu „PiShrink verkleinert Raspberry Pi-Images“

  1. Avatar von

    Genial, genau das, was ich lange Zeit gesucht habe.

    Nach voller Einrichtung meines OMV-Nas-Servers auf dem Raspberry will ich das Image sichern und später auch auf einer 8Gb-Karte (damals hatte ich nur eine 16er zur Hand) notfalls wiederherstellen können.

    Vielen Dank!

  2. Avatar von Sergej

    Danke für den Artikel. Hab diese Seite zufällig gefunden und bin froh darüber. Man erfährt hier immer wieder mal Interessante und nützliche Sachen.

  3. Avatar von Marek

    Hallo Christoph, seit Jahren schaue ich in unregelmäßigen Abständen auf deiner Seite vorbei. Nahezu jedes Mal entdecke ich in deinen dann zurückliegenden veröffentlichten Einträgen Neues und Interessantes für mich. Vielen Dank, dass du pishrink entdeckt und uns an dieser Entdeckung hast teilnehmen lassen!! Das Skript ist gerade dabei ein Raspi-Image von einer 16 GB micro SDHC-Karte zu verkleinern. Grüße, M.

    Link: http://www.forum-raspberrypi.de/Thread-raspbian-image-verkleinern-mit-pishrink

  4. Avatar von Norbert
    Norbert

    Hi Christoph,
    SUPER!! Genau das, was ich brauchte.
    Habe in meinem RasPi 3B eine 32-GB-Karte und es ist extrem lästig, wenn die Backups so viel Platz einnehmen.
    ABER:
    Obwohl ich ein orginal Raspbian einsetze, funktioniert die automatische Expansion nach dem Restore & Boot mit der neuen SD nicht!
    Mache ich was falsch, oder geht das beim RasPi 3B nicht?

    Ist allerdings auch kein Beinbruch, da im raspi-config die Möglichkeit besteht, das Dateisystem zu expandieren.
    Danach ist wieder die gesamte SD nutzbar.

    Grüße
    Norbert aus Berlin

  5. Avatar von Nils

    Achtung, scheint explizit nicht für NOOB-Raspian zu funktionieren! Kurze Info wäre für mich hilfreich gewesen…

    Trotzdem Danke für die tollen Fundstücke!

  6. Avatar von Kev

    Hi,
    ich komme leider nicht weiter. Habe ubuntu auf VM laufen.

    $ sudo ./pishrink.sh pibackup.img

    Creating new /etc/rc.local
    /dev/loop0: Inodes that were part of a corrupted orphan linked list found.

    /dev/loop0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
    (i.e., without -a or -p options)
    resize2fs 1.42.13 (17-May-2015)
    Please run ‚e2fsck -f /dev/loop0‘ first.

    ./pishrink.sh: line 148: 7779968 – : syntax error: operand expected (error token is „- „)
    resize2fs 1.42.13 (17-May-2015)
    Please run ‚e2fsck -f /dev/loop0‘ first.

    ERROR: resize2fs failed…

  7. Avatar von Karl

    Hallo Christoph,
    Expansion nach dem Raspbian Restore & Boot mit der neuen SD geht definitiv nicht!
    Ich habe es nun mehrfach probiert. Gibt es hier weitere Informationen von Deiner Seite?
    Danke

  8. Avatar von Michael

    Beim Versuch eine PI-Installation auf einer 32 GB SD Karte (Quelle) auf eine 16 GB Karte zu kopieren kann ich das Image von der Quelle mit dd erzeugen, bekomme aber die Fehlermeldung
    Fehler: Es können keine überlappenden Partitionen existieren.

    was mache ich falsch?

    sudo dd if=/dev/sdb of=/mnt/share/sdb.img

    lsblk
    NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
    sda 8:0 0 12G 0 disk
    └─sda1 8:1 0 12G 0 part /
    sdb 8:16 1 29,7G 0 disk
    ├─sdb1 8:17 1 1,4G 0 part
    ├─sdb2 8:18 1 1K 0 part
    ├─sdb5 8:21 1 32M 0 part /media/michael/SETTINGS
    ├─sdb6 8:22 1 66M 0 part /media/michael/boot
    └─sdb7 8:23 1 28,2G 0 part /media/michael/root
    sr0 11:0 1 1,4G 0 rom /media/michael/Ubuntu 17.10 amd64

    sudo fdisk -l sdb.img
    Medium sdb.img: 29,7 GiB, 31914983424 Bytes, 62333952 Sektoren
    Einheiten: sectors von 1 * 512 = 512 Bytes
    Sektorengröße (logisch/physisch): 512 Bytes / 512 Bytes
    I/O Größe (minimal/optimal): 512 Bytes / 512 Bytes
    Typ der Medienbezeichnung: dos
    Medienkennung: 0x000baf66

    Gerät Boot Start Ende Sektoren Größe Id Typ
    sdb.img1 8192 2994140 2985949 1,4G e W95 FAT16 (LBA)
    sdb.img2 2994141 62333951 59339811 28,3G 5 Erweiterte
    sdb.img5 2998272 3063805 65534 32M 83 Linux
    sdb.img6 3063808 3198975 135168 66M c W95 FAT32 (LBA)
    sdb.img7 3203072 62333951 59130880 28,2G 83 Linux

    pishrink-Aufruf
    sudo /home/michael/bin/pishrink.sh /mnt/share/sdb.img /mnt/share/sdb_klein.img

    sudo /home/michael/bin/pishrink.sh /mnt/share/sdb.img /mnt/share/sdbklein.img
    [sudo] Passwort für michael:
    Copying /mnt/share/sdb.img to /mnt/share/sdb
    klein.img…
    Creating new /etc/rc.local
    root: 145429/1851392 Dateien (0.2% nicht zusammenhängend), 1322279/7391360 Blöcke
    resize2fs 1.43.5 (04-Aug-2017)
    resize2fs 1.43.5 (04-Aug-2017)
    Die Größe des Dateisystems auf /dev/loop0 wird auf 1693646 (4k) Blöcke geändert.
    Start von Durchgang 2 (max = 506911)
    Blöcke werden verschoben XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Start von Durchgang 3 (max = 226)
    Die Inode-Tabelle wird gelesenXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Start von Durchgang 4 (max = 12835)
    Die Inode-Referenzen werden aktualisiertXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Das Dateisystem auf /dev/loop0 is nun 1693646 (4k) Blöcke lang.

    Fehler: Es können keine überlappenden Partitionen existieren.
    Shrunk /mnt/share/sdb_klein.img from 30G to 1,6G

  9. Avatar von mehlanmich@gmx. net
    mehlanmich@gmx. net

    Gibt es inzwischen eine Version von pishrink, die mit NOOBS-Partitionen zurecht kommt oder evtl. ein anderes Tool, mit dem man die SD Karten-Images für die Übertragung auf eine kleine Karte anpassen kann?

  10. Avatar von Solderdot
    Solderdot

    Danke für den Artikel Tolle Sache.
    Funktioniert aber nicht ganz so gut wie erwartet: 64GB SD-Karte zu 30% benutzt. Das Image, das PiShrink erzeugt, passt aber dennoch nicht auf eine 32GB SD-Karte. Ich hätte gedacht, dass das locker passen sollte…

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Markdown wird unterstützt: **fett**, _kursiv_, [Linktext](URL), `Code`, Zeilen mit - für Listen, 1. für nummerierte Listen, dreifache Backticks für Codeblöcke.

Über den Blog

Seit 2006 probiere ich hier aus, was Linux, freie Software und die passende Hardware so hergeben – von Distributions-Tests bis zum Raspberry-Pi-Projekt. Praxisnah statt bloßem Nachrichtenticker.

Zuletzt auf Mastodon

Wo wir beim Thema TuxSucht sind. @gnulinux hat einen tollen Beitrag über das "Projekt" veröffentlicht.

gnulinux.ch/tux-macht-suechtig…

#Linux #foss #opensource

Kategorien

Blog unterstützen

Gefällt dir, was du hier liest? Mit einer kleinen Spende hilfst du, Hosting und neue Testgeräte zu finanzieren – und sorgst nebenbei für den nötigen Kaffee.

Linux und Ich — PiShrink verkleinert Raspberry Pi-Images
https://linuxundich.de/raspberry-pi/pishrink-verkleinert-raspberry-pi-images/ — gedruckt am 23. September 2026