Repository: qrti/shrink Branch: master Commit: 4f4cf14d3e28 Files: 8 Total size: 46.1 KB Directory structure: gitextract_ilp038ff/ ├── .gitattributes ├── README.md ├── deprecated/ │ ├── readme_071.md │ ├── readme_081.md │ ├── shrink_071.sh │ ├── shrink_081.sh │ └── shrink_092.sh └── script/ └── shrink.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: README.md ================================================ # **shrink** **Linux bash script to resize Raspberry SD card images** consider further [remarks](#remarks) ### **new version** \- dependency tests \- low memory warning \- argument handling and help screen \- automated size retrieving from GParted \- progress bars with ETA for all time consuming actions \- environment variable support --- ### **download** download repository from GitHub, unzip and copy for example to: ~/shrink **or** copy script to current directory `wget https://raw.github.com/qrti/shrink/master/script/shrink.sh` **or** check if git is installed `$ git --version` if git is not installed `$ sudo apt-get install git-all` clone shrink repository to current directory `$ git clone https://github.com/qrti/shrink.git` --- ### **necessary installs** `$ sudo apt-get install gparted` `$ sudo apt-get install pv` --- ### **prepare** **before executing the script the first time, insert your SD card** enter the following at the command line and find the name of your SD device and partitions `$ df -h` now extract the device name example 1 for list entries like: /dev/sdb1 + /dev/sdb2 omit digit at the end result: /dev/sdb example 2 for list entries like: /dev/mmcblk1p1 + /dev/mmcblk1p2 omit p and digit at the end result: /dev/mmcblk1 **make script executable once** change directory `$ cd ~/shrink/script` `$ chmod 755 shrink.sh` **or** `$ chmod a+x shrink.sh` --- ### **execute** **usage and help** ``` Usage: (sudo) shrink.sh [] (sudo) shrink.sh -h | --help (sudo) shrink.sh ``` examples: `$ sudo ./shrink.sh` read, resize and zero fill image `$ sudo ./shrink.sh --compress --skip-fill` read, resize and compress image without zero fill `$ sudo ./shrink.sh --device /dev/mmcblk1` read, resize and zero fill image from device /dev/mmcblk1 the help screen shows options and their current default values ``` Options: -h --help show this screen --user specify user who should own output files (default: root) --device source and target SD card device (default: /dev/sdb) --date_name image name, alternative with date and time: "image_191003113547 (default: image)" --image image name with extension (default: image.img) --details gparted details file path and name (default: ~/gparted_details.htm) --compress compress new image (an extra file is generated) (default: false) --write write new image to SD card (default: false) --skip-read read image from SD card (false for an already existing image) (default: true) --skip-resize resize image with GParted (default: true) --skip-fill fill empty space of new image with zeroes, only possible if RESIZE=true (default: true) ``` **changing default values by editing the script** `$ nano shrink.sh` example for: /dev/sdb1 + /dev/sdb2 omit digit ``` DEVICE=${DEVICE:-/dev/sdb} ``` example for: /dev/mmcblk1p1 + /dev/mmcblk1p2 omit p and digit at the end ``` DEVICE=${DEVICE:-/dev/mmcblk1} ``` your username is filled in automatically, to override edit USER ``` USER=${USER:-`whoami`} ``` **changing default values by using environment variables** default values can be overridden by passing them as env vars for example to set DEVICE and READ enter at the command line `$ sudo DEVICE=/dev/sdb READ=false ./shrink.sh` explore the top of the script to configure some more things --- ### **remarks** \- use this script completely at your own risk be sure to have backups of your data \- new versions not widely tested yet look for previous versions in directory 'deprecated' \- runs on physical or virtual Linux desktop systems \- cannot handle Raspberry NOOBS images \- do not shrink images to minimum otherwise they won't start on your Raspberry especially Raspbian Full *Desktop* images need some extra space, about >= 250 MB are advised Raspbian *Lite* images might be more moderate \- when starting from a shrinked SD card for the first time expand the filesystem to fill its space by raspi-config `sudo raspi-config` -> *Expand Filesystem* `sudo reboot` **or** from command line `sudo raspi-config --expand-rootfs` `sudo reboot` \- the script is 'half automatic' meaning at one point it will start GParted on desktop and guide you what to do \- progress display of 'fill empty space' may not end at 100 % exactly because of difficult file system overhead calculation nevertheless space will be filled correctly \- the script was developed and tested on a VirtualBox Windows host with Linux Mint guest \- inspired by [http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php](http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php) Donations are welcome! [![https://www.paypal.com](https://www.paypalobjects.com/webstatic/en_US/btn/btn_donate_pp_142x27.png)](https://www.paypal.com/donate?business=qrt@qland.de¤cy_code=USD&amount=5.00) --- ### history V0.5 initial version, script keel fix by Barleyman V0.6 mmcblk naming support V0.7 simplifications V0.71 adaption for parted 3.2, p -> print V0.8 automated size retrieving from GParted progress bars with ETA for all time consuming actions V0.81 default value override by environment variables thanks to Leon Miller-Out V0.9 argument handling and help screen thanks to Pedro Figueiredo e Silva V0.91 low memory warning gparted details path hint V0.92 dependency tests thanks to Tom Troyer V0.93 correction for chown warning - - - ### copyright shrink is published under the terms of ISC license Copyright (c) 2025 [qrt@qland.de](mailto:qrt@qland.de) Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ================================================ FILE: deprecated/readme_071.md ================================================ # shrink V0.71 there is also a [newer version](README.md) #### Linux bash script to resize Raspberry SD card images consider further [remarks](#remarks) #### download download repository from GitHub, unzip and copy for example to: ~/shrink **or** copy script to current directory `wget https://raw.github.com/qrti/shrink/master/script/shrink_071.sh` **or** check if git is installed `$ git --version` if git is not installed `$ sudo apt-get install git-all` clone shrink repository to current directory `$ git clone https://github.com/qrti/shrink.git` - - - #### necessary installs `$ sudo apt-get install gparted` `$ sudo apt-get install dcfldd` - - - #### configure before executing the script the first time, insert your SD card enter the following at the command line and find the name of your SD device and partitions `$ df -h` edit the script and enter your data between the quotation marks `$ nano shrink_071.sh` example for /dev/sdd1 + 2 (omit digit) ``` DEVICE="/dev/sdd" ``` example for /dev/mmcblk0p1 + 2 (omit px) ``` DEVICE="/dev/mmcblk0" ``` fill in your Linux user name at USER ``` USER="your user name" ``` explore the top of the script to configure some more things - - - #### execute change directory `$ cd ~/shrink` make script executable once `$ chmod 755 shrink_071.sh` **or** `$ chmod a+x shrink_071.sh` execute script `$ sudo ./shrink_071.sh` - - - #### remarks \- use this script completely at your own risk \- runs on physical or virtual Linux desktop systems \- cannot handle NOOBS images \- do not shrink images to minimum, otherwise they won't start on your Raspberry, especially Raspbian Full *Desktop* images need some extra space, about >= 250 MB are advised, Raspbian *Lite* images might be more moderate \- when starting from a shrinked SD card for the first time, expand the filesystem to fill its space by raspi-config `sudo raspi-config` -> *Expand Filesystem* `sudo reboot` **or** from command line `sudo raspi-config --expand-rootfs` `sudo reboot` \- the script is 'half automatic', meaning at one point it will start GParted on desktop and guide you what to do \- the script was developed and tested on a VirtualBox Windows host with Linux Mint guest \- inspired by [http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php](http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php) Donations are welcome! [![https://www.paypal.com](https://www.paypalobjects.com/webstatic/en_US/btn/btn_donate_pp_142x27.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E7JNEDMHAJ3TJ) - - - #### history V0.5 initial version, script keel fix by Barleyman V0.6 mmcblk naming support V0.7 simplifications V0.71 adaption for parted 3.2, p -> print - - - #### copyright shrink is published under the terms of ISC license Copyright (c) 2018 [qrt@qland.de](mailto:qrt@qland.de) Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ================================================ FILE: deprecated/readme_081.md ================================================ # shrink **Linux bash script to resize Raspberry SD card images** consider further [remarks](#remarks) ### new version \- automated size retrieving from GParted \- progress bars with ETA for all time consuming actions \- environment variable support **not widely tested yet, be sure to have backups of your data** or use [previous version](readme_071.md) ### download download repository from GitHub, unzip and copy for example to: ~/shrink **or** copy script to current directory `wget https://raw.github.com/qrti/shrink/master/script/shrink.sh` **or** check if git is installed `$ git --version` if git is not installed `$ sudo apt-get install git-all` clone shrink repository to current directory `$ git clone https://github.com/qrti/shrink.git` - - - ### necessary installs `$ sudo apt-get install gparted` `$ sudo apt-get install pv` - - - ### configure before executing the script the first time, insert your SD card enter the following at the command line and find the name of your SD device and partitions `$ df -h` edit the script and enter your data between the quotation marks `$ nano shrink.sh` example for /dev/sdb1 + 2 (omit digit) ``` DEVICE=${DEVICE:-/dev/sdb} ``` example for /dev/mmcblk0p1 + 2 (omit p and digit) ``` DEVICE=${DEVICE:-/dev/mmcblk0} ``` your username is filled in automatically, to override edit USER ``` USER=${USER:-`whoami`} ``` **using environment variables** default values can be overridden by passing them as env vars for example to set DEVICE and READ enter at the command line `$ sudo DEVICE=/dev/sdb READ=false ./shrink.sh` explore the top of the script to configure some more things - - - ### execute change directory `$ cd ~/shrink` make script executable once `$ chmod 755 shrink.sh` **or** `$ chmod a+x shrink.sh` execute script `$ sudo ./shrink.sh` - - - ### remarks \- use this script completely at your own risk \- runs on physical or virtual Linux desktop systems \- cannot handle NOOBS images \- do not shrink images to minimum, otherwise they won't start on your Raspberry, especially Raspbian Full *Desktop* images need some extra space, about >= 250 MB are advised, Raspbian *Lite* images might be more moderate \- when starting from a shrinked SD card for the first time, expand the filesystem to fill its space by raspi-config `sudo raspi-config` -> *Expand Filesystem* `sudo reboot` **or** from command line `sudo raspi-config --expand-rootfs` `sudo reboot` \- the script is 'half automatic', meaning at one point it will start GParted on desktop and guide you what to do \- progress display of 'fill empty space' may not end at 100 % exactly because of difficult file system overhead calculation, nevertheless space will be filled correctly \- the script was developed and tested on a VirtualBox Windows host with Linux Mint guest \- inspired by [http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php](http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php) Donations are welcome! [![https://www.paypal.com](https://www.paypalobjects.com/webstatic/en_US/btn/btn_donate_pp_142x27.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=E7JNEDMHAJ3TJ) - - - ### history V0.5 initial version, script keel fix by Barleyman V0.6 mmcblk naming support V0.7 simplifications V0.71 adaption for parted 3.2, p -> print V0.8 automated size retrieving from GParted progress bars with ETA for all time consuming actions V0.81 default value override by environment variables thanks to Leon Miller-Out - - - ### copyright shrink is published under the terms of ISC license Copyright (c) 2018 [qrt@qland.de](mailto:qrt@qland.de) Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ================================================ FILE: deprecated/shrink_071.sh ================================================ #!/bin/bash # shrink V0.71 180527 qrt@qland.de # linux bash script to resize Raspberry SD card images # # inspired by # http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php # # necessary installs # sudo apt-get update && sudo apt-get install dcfldd # sudo apt-get update && sudo apt-get install gparted DEVICE="/dev/sdd" # source and target SD card device, examples: /dev/sdd, /dev/mmcblk0 ... USER="your user name" # linux user name IMAGE_NAME="image" # image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S")" IMAGE="${IMAGE_NAME}.img" # image name with extension LOOP=$(losetup -f) READ=true # read image from SD card (false for an already existing image) RESIZE=true # resize image with GParted FILL=true # fill empty space of new image with zeroes, only possible if RESIZE=true COMPRESS=false # compress new image (an extra file is generated) WRITE=false # write new image to SD card pause(){ printf "\n" printf "$1\n" read -p "press [Enter] to continue, CTRL-C to abort" key printf "\n" } checkDevice(){ if [ "$1" == "" -o "$(df -h --output=source | grep "$DEVICE")" == "" ]; then printf "device '$1' does not exist\n" printf "> check SD card devices with 'df -h'\n" printf "> re-insert SD card if necessary\n" printf "> edit DEVICE= in script if necessary\n\n" exit 1 fi } echo "shrink V0.71 180527 qrt@qland.de" if [ $(id -u) -ne 0 ]; then printf "\n" printf "script must be run as root\n" printf "> try 'sudo ./shrink'\n\n" exit 1 fi if [ "$USER" == "" ]; then printf "\n" printf "user not set\n" printf "> edit USER= in script\n\n" exit 1 fi if [ $READ == true ]; then if [ -f $IMAGE ]; then pause "file '$IMAGE' already exists and will be overwritten" echo -ne '\033[1A' # one line up fi pause "insert source SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE sudo umount $DEVICE?* && echo unmount ok || exit 1 sudo dcfldd if=$DEVICE of=$IMAGE && echo image read ok || exit 1 sudo sync pause "remove SD card" echo -ne '\033[1A' # one line up fi echo sudo chown $USER.$USER $IMAGE && echo owner and group ok || exit 1 if [ $RESIZE == true ]; then #sudo fdisk -l $IMAGE #read -p "enter Start of part 2: " start start="$(sudo parted $IMAGE -ms unit s print | grep "^2" | cut -f2 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP >/dev/null 2>&1 # remove possible open loop sudo losetup $LOOP $IMAGE -o $((start*512)) && echo loop setup ok || exit 1 echo echo "GParted desktop is started now" echo "- go to GParted desktop window" echo "- select '$LOOP'" echo "- menu 'Partition / Resize/Move'" echo "- change value of 'New Size' about >= 250 MB above 'Minimum Size'" echo "- press button 'Resize/Move'" echo "- menu 'Edit / Apply All Operations' and press Apply" echo "- wait until GParted is ready - do not close dialog yet" echo "- expand 'Details / Shrink.. / shrink.. / resize2fs -p $LOOP xxxxxxxK'" echo "- note down size xxxxxxx" echo "- close dialog and exit GParted" sudo gparted $LOOP >/dev/null 2>&1 # supresses GLib messages echo read -p "enter noted size xxxxxxxx: " size echo sudo losetup -d $LOOP && echo loop remove ok || exit 1 sudo losetup $LOOP $IMAGE && echo loop setup ok || exit 1 newsize="+${size}K" printf "d\n2\nn\np\n2\n$start\n$newsize\np\nw\n" | sudo fdisk $LOOP >/dev/null 2>&1 echo resize ok #sudo fdisk -l $LOOP #read -p "enter End of part 2: " end end="$(sudo parted $LOOP -ms unit s print | grep "^2" | cut -f3 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP && echo loop remove ok || exit 1 truncate -s $(((end+1)*512)) $IMAGE && echo truncate ok || exit 1 if [ $FILL == true ]; then echo echo fill empty space sudo losetup $LOOP $IMAGE -o $((start*512)) sudo mkdir -p /mnt/imageroot sudo mount $LOOP /mnt/imageroot sudo dcfldd if=/dev/zero of=/mnt/imageroot/zero.txt sudo rm /mnt/imageroot/zero.txt sudo umount /mnt/imageroot sudo rmdir /mnt/imageroot sudo losetup -d $LOOP echo fill empty space ok fi fi if [ $COMPRESS == true ]; then echo echo compress image zip $IMAGE_NAME.zip $IMAGE && echo compress ok || echo compress failed fi if [ $WRITE == true ]; then pause "insert target SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE sudo umount $DEVICE?* && echo unmount ok || exit 1 sudo dcfldd if=$IMAGE of=$DEVICE && echo image write ok || exit 1 sudo sync echo echo remove SD card fi echo echo ready echo ================================================ FILE: deprecated/shrink_081.sh ================================================ #!/bin/bash # shrink V0.81 180707 qrt@qland.de # linux bash script to resize Raspberry SD card images, progress version # # inspired by # http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php # make script executable once # chmod a+x shrink.sh # necessary installs # sudo apt-get install gparted # sudo apt-get install pv ### # configuration # default values can be overridden by passing them as env vars # e.g. sudo DEVICE=/dev/sda READ=false ./shrink.sh ### USER=${USER:-`whoami`} # specify user who should own output files DEVICE=${DEVICE:-/dev/sdb} # source and target SD card device, examples: /dev/sdd, /dev/mmcblk0 ... IMAGE_NAME=${IMAGE_NAME:-image} # image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S")" IMAGE=${IMAGE:-${IMAGE_NAME}.img} # image name with extension DETAILS=${DETAILS:-~/gparted_details.htm} # gparted details file path and name READ=${READ:-true} # read image from SD card (false for an already existing image) RESIZE=${RESIZE:-true} # resize image with GParted FILL=${FILL:-true} # fill empty space of new image with zeroes, only possible if RESIZE=true COMPRESS=${COMPRESS:-false} # compress new image (an extra file is generated) WRITE=${WRITE:-false} # write new image to SD card LOOP=$(losetup -f) pause(){ printf "\n" printf "$1\n" read -p "press [Enter] to continue, CTRL-C to abort" key printf "\n" } checkDevice(){ if [ "$1" == "" -o "$(df -h --output=source | grep "$DEVICE")" == "" ]; then printf "device '$1' does not exist\n" printf "> check SD card devices with 'df -h'\n" printf "> re-insert SD card if necessary\n" printf "> edit DEVICE= in script if necessary\n\n" exit 1 fi } echo "shrink V0.81 180707 qrt@qland.de" if [ $(id -u) -ne 0 ]; then printf "\n" printf "script must be run as root\n" printf "> try 'sudo ./shrink'\n\n" exit 1 fi if [ "$USER" == "" ]; then printf "\n" printf "user not set\n" printf "> edit USER= in script\n\n" exit 1 fi if [ $READ == true ]; then if [ -f $IMAGE ]; then pause "file '$IMAGE' already exists and will be overwritten" echo -ne '\033[1A' # one line up fi pause "insert source SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsize="$(($(blockdev --getsize64 $DEVICE)/1024))K" sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "generate image from SD card" sudo dd if=$DEVICE status=none | pv -s $bsize | dd of=$IMAGE bs=4096 status=none \ && echo image read ok || exit 1 sudo sync pause "remove SD card" echo -ne '\033[1A' # one line up fi echo sudo chown $USER.$USER $IMAGE && echo owner and group ok || exit 1 if [ $RESIZE == true ]; then #sudo fdisk -l $IMAGE #read -p "enter Start of part 2: " start start="$(sudo parted $IMAGE -ms unit s print | grep "^2" | cut -f2 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP >/dev/null 2>&1 # remove possible open loop sudo losetup $LOOP $IMAGE -o $((start*512)) && echo loop setup ok || exit 1 echo echo "GParted desktop is started now" echo "- go to GParted desktop window" echo "- select '$LOOP'" echo "- menu 'Partition / Resize/Move'" echo "- change value of 'New Size' about >= 250 MB above 'Minimum Size'" echo "- press button 'Resize/Move'" echo "- menu 'Edit / Apply All Operations' and press Apply" echo "- wait until GParted is ready - do not close dialog yet" echo "- press button 'Save Details' and 'Save' in file requester" echo "- close dialog and exit GParted" echo rm -f ~/gparted_details.htm # remove old details sudo gparted $LOOP >/dev/null 2>&1 # supresses GLib messages if [ ! -f $DETAILS ]; then # check details exist echo "gparted details file not found" exit 1 fi size=$(awk '/resize2fs -p / {print $4;}' $DETAILS | awk 'BEGIN { FS="K"; } { print $1; }') rm -f ~/gparted_details.htm # remove details if [ -z $size ]; then # check size echo "size not found in details" exit 1 elif [ $size -lt 512000 ]; then echo "suspicious small filesize" exit 1 fi sudo losetup -d $LOOP && echo loop remove ok || exit 1 sudo losetup $LOOP $IMAGE && echo loop setup ok || exit 1 newsize="+${size}K" printf "d\n2\nn\np\n2\n$start\n$newsize\np\nw\n" | sudo fdisk $LOOP >/dev/null 2>&1 echo resize ok #sudo fdisk -l $LOOP #read -p "enter End of part 2: " end end="$(sudo parted $LOOP -ms unit s print | grep "^2" | cut -f3 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP && echo loop remove ok || exit 1 truncate -s $(((end+1)*512)) $IMAGE && echo truncate ok || exit 1 if [ $FILL == true ]; then echo echo fill empty space sudo losetup $LOOP $IMAGE -o $((start*512)) sudo mkdir -p /mnt/imageroot sudo mount $LOOP /mnt/imageroot bsize="$(($(df -h -B1K | grep ^$LOOP | awk '{print $4}')*11/10))K" # +10% progress bar fs overhead correction sudo dd if=/dev/zero | pv -s $bsize | dd of=/mnt/imageroot/zero.txt >/dev/null 2>&1 sudo rm /mnt/imageroot/zero.txt sudo umount /mnt/imageroot sudo rmdir /mnt/imageroot sudo losetup -d $LOOP echo fill empty space ok fi fi if [ $COMPRESS == true ]; then echo echo compress image tar pcf - $IMAGE | pv -s $(du -sb $IMAGE | awk '{print $1}') | gzip > $IMAGE_NAME.tar.gz \ && echo compress ok || echo compress failed fi if [ $WRITE == true ]; then pause "insert target SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsize="$(($(blockdev --getsize64 $DEVICE)/1024))K" sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "write image to SD card" sudo dd if=$IMAGE status=none | pv -s $bsize | dd of=$DEVICE bs=4096 status=none \ && echo image write ok || exit 1 sudo sync echo echo remove SD card fi echo echo ready echo ================================================ FILE: deprecated/shrink_092.sh ================================================ #!/bin/bash # shrink V0.92 191008 qrt@qland.de # linux bash script to resize Raspberry SD card images, progress version # # inspired by # http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php # make script executable once # chmod a+x shrink.sh # necessary installs # sudo apt-get install gparted # sudo apt-get install pv ### # configuration # default values can be overridden by passing them as env vars # e.g. sudo DEVICE=/dev/sda READ=false ./shrink.sh ### SHRINK_VERSION="V0.92 191008" trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR USER=${USER:-`whoami`} # specify user who should own output files DEVICE=${DEVICE:-/dev/sdb} # source and target SD card device, examples: /dev/sdd, /dev/mmcblk0 ... IMAGE_NAME=${IMAGE_NAME:-image} # image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S")" IMAGE=${IMAGE:-${IMAGE_NAME}.img} # image name with extension DETAILS=${DETAILS:-~/gparted_details.htm} # gparted details file path and name READ=${READ:-true} # read image from SD card (false for an already existing image) RESIZE=${RESIZE:-true} # resize image with GParted FILL=${FILL:-true} # fill empty space of new image with zeroes, only possible if RESIZE=true COMPRESS=${COMPRESS:-false} # compress new image (an extra file is generated) WRITE=${WRITE:-false} # write new image to SD card LOOP=$(losetup -f) _ME=$(basename "${0}") _print_help() { cat <] (sudo) ${_ME} -h | --help (sudo) ${_ME} Options: -h --help show this screen --user specify user who should own output files (default: ${USER}) --device source and target SD card device (default: ${DEVICE}) --date_name image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S") (default: ${IMAGE_NAME})" --image image name with extension (default: ${IMAGE}) --details gparted details file path and name (default: ${DETAILS}) --compress compress new image (an extra file is generated) (default: ${COMPRESS}) --write write new image to SD card (default: ${WRITE}) --skip-read read image from SD card (false for an already existing image) (default: ${READ}) --skip-resize resize image with GParted (default: ${RESIZE}) --skip-fill fill empty space of new image with zeroes, only possible if RESIZE=true (default: ${FILL}) HEREDOC } function _parse { # Gather commands while (( "${#}" )) do case "${1}" in --user) USER="${2}" shift shift ;; --device) DEVICE="${2}" shift shift ;; --date_name) IMAGE_NAME="image_$(date +"%y%m%d%H%M%S")" shift ;; --image) IMAGE="${2}" shift shift ;; --details) DETAILS="${2}" shift shift ;; --skip-read) READ=false shift ;; --skip-resize) RESIZE=false shift ;; --skip-fill) FILL=false shift ;; --compress) COMPRESS=true shift ;; --write) WRITE=true shift ;; *|-*|--*=) # unsupported flags echo "Unknown ${1}" exit 1 ;; esac done } pause(){ printf "\n" printf "$1\n" read -p "press [Enter] to continue, CTRL-C to abort" key printf "\n" } checkDevice(){ if [ "$1" == "" -o "$(df -h --output=source | grep "$DEVICE")" == "" ]; then printf "device '$1' does not exist\n" printf "> check SD card devices with 'df -h'\n" printf "> re-insert SD card if necessary\n" printf "> edit DEVICE= in script if necessary\n\n" exit 1 fi } function _main { echo "shrink ${SHRINK_VERSION} qrt@qland.de" if [ $(id -u) -ne 0 ]; then printf "\n" printf "script must be run as root\n" printf "> try 'sudo ./shrink'\n\n" exit 1 fi if [ "$USER" == "" ]; then printf "\n" printf "user not set\n" printf "> edit USER= in script\n\n" exit 1 fi if [ $READ == true ]; then if [ -f $IMAGE ]; then pause "file '$IMAGE' already exists and will be overwritten" echo -ne '\033[1A' # one line up fi pause "insert source SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsizek=$(($(blockdev --getsize64 $DEVICE)/1024)) bsizem=$(($bsizek/1024)) freem=$((`df -k --output=avail "$PWD" | tail -n1`/1024)) if [ $freem -lt $(($bsizem*3)) ]; then pause "warning: free memory "$freem"M is possibly too low for image (+ zip)" echo -ne '\033[1A' # one line up fi sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "generate image from SD card" bsize=$bsizek"K" sudo dd if=$DEVICE status=none | pv -s $bsize | dd of=$IMAGE bs=4096 status=none \ && echo image read ok || exit 1 sudo sync pause "remove SD card" echo -ne '\033[1A' # one line up fi echo sudo chown $USER.$USER $IMAGE && echo owner and group ok || exit 1 if [ $RESIZE == true ]; then #sudo fdisk -l $IMAGE #read -p "enter Start of part 2: " start start="$(sudo parted $IMAGE -ms unit s print | grep "^2" | cut -f2 -d: | sed 's/[^0-9]*//g')" sudo losetup -d ${LOOP} >/dev/null 2>&1 # remove possible open loop sudo losetup ${LOOP} ${IMAGE} -o $((start*512)) && echo loop setup ok || exit 1 echo echo "GParted desktop is started now" echo "- go to GParted desktop window" echo "- select '$LOOP'" echo "- menu 'Partition / Resize/Move'" echo "- change value of 'New Size' about >= 250 MB above 'Minimum Size'" echo "- press button 'Resize/Move'" echo "- menu 'Edit / Apply All Operations' and press Apply" echo "- wait until GParted is ready - do not close dialog yet" echo "- press button 'Save Details' and 'Save' in file requester" echo " details are saved to $DETAILS" echo "- close dialog and exit GParted" echo rm -f ~/gparted_details.htm # remove old details sudo gparted $LOOP >/dev/null 2>&1 # supresses GLib messages if [ ! -f $DETAILS ]; then # check details exist echo "gparted details file not found" exit 1 fi size=$(awk '/resize2fs -p / {print $4;}' $DETAILS | awk 'BEGIN { FS="K"; } { print $1; }') rm -f ~/gparted_details.htm # remove details if [ -z $size ]; then # check size echo "size not found in details" exit 1 elif [ $size -lt 512000 ]; then echo "suspicious small filesize" exit 1 fi sudo losetup -d $LOOP && echo loop remove ok || exit 1 sudo losetup $LOOP $IMAGE && echo loop setup ok || exit 1 newsize="+${size}K" printf "d\n2\nn\np\n2\n$start\n$newsize\np\nw\n" | sudo fdisk $LOOP >/dev/null 2>&1 echo resize ok #sudo fdisk -l $LOOP #read -p "enter End of part 2: " end end="$(sudo parted $LOOP -ms unit s print | grep "^2" | cut -f3 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP && echo loop remove ok || exit 1 truncate -s $(((end+1)*512)) $IMAGE && echo truncate ok || exit 1 if [ $FILL == true ]; then echo echo fill empty space sudo losetup $LOOP $IMAGE -o $((start*512)) sudo mkdir -p /mnt/imageroot sudo mount $LOOP /mnt/imageroot bsize="$(($(df -h -B1K | grep ^$LOOP | awk '{print $4}')*11/10))K" # +10% progress bar fs overhead correction sudo dd if=/dev/zero | pv -s $bsize | dd of=/mnt/imageroot/zero.txt >/dev/null 2>&1 sudo rm /mnt/imageroot/zero.txt sudo umount /mnt/imageroot sudo rmdir /mnt/imageroot sudo losetup -d $LOOP echo fill empty space ok fi fi if [ $COMPRESS == true ]; then echo echo compress image tar pcf - $IMAGE | pv -s $(du -sb $IMAGE | awk '{print $1}') | gzip > $IMAGE_NAME.tar.gz \ && echo compress ok || echo compress failed fi if [ $WRITE == true ]; then pause "insert target SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsize="$(($(blockdev --getsize64 $DEVICE)/1024))K" sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "write image to SD card" sudo dd if=$IMAGE status=none | pv -s $bsize | dd of=$DEVICE bs=4096 status=none \ && echo image write ok || exit 1 sudo sync echo echo remove SD card fi echo echo ready echo } if [ "${1:-}" == -h ] || [ "${1:-}" == --help ]; then _print_help else # check script dependencies command -v gparted >/dev/null 2>&1 || { echo >&2 "Cannot locate gparted. Is it installed? Aborting."; exit 1; } command -v pv >/dev/null 2>&1 || { echo >&2 "Cannot locate pv. Is it installed? Aborting."; exit 1; } echo "calling parser" _parse "$@" _main "$@" fi ================================================ FILE: script/shrink.sh ================================================ #!/bin/bash # shrink V0.93 241231 qrt@qland.de # linux bash script to resize Raspberry SD card images, progress version # # inspired by # http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php # make script executable once # chmod a+x shrink.sh # necessary installs # sudo apt-get install gparted # sudo apt-get install pv ### # configuration # default values can be overridden by passing them as env vars # e.g. sudo DEVICE=/dev/sda READ=false ./shrink.sh ### SHRINK_VERSION="V0.93 241231" trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR USER=${USER:-`whoami`} # specify user who should own output files DEVICE=${DEVICE:-/dev/sdb} # source and target SD card device, examples: /dev/sdd, /dev/mmcblk0 ... IMAGE_NAME=${IMAGE_NAME:-image} # image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S")" IMAGE=${IMAGE:-${IMAGE_NAME}.img} # image name with extension DETAILS=${DETAILS:-~/gparted_details.htm} # gparted details file path and name READ=${READ:-true} # read image from SD card (false for an already existing image) RESIZE=${RESIZE:-true} # resize image with GParted FILL=${FILL:-true} # fill empty space of new image with zeroes, only possible if RESIZE=true COMPRESS=${COMPRESS:-false} # compress new image (an extra file is generated) WRITE=${WRITE:-false} # write new image to SD card LOOP=$(losetup -f) _ME=$(basename "${0}") _print_help() { cat <] (sudo) ${_ME} -h | --help (sudo) ${_ME} Options: -h --help show this screen --user specify user who should own output files (default: ${USER}) --device source and target SD card device (default: ${DEVICE}) --date_name image name, alternative with date and time: "image_$(date +"%y%m%d%H%M%S") (default: ${IMAGE_NAME})" --image image name with extension (default: ${IMAGE}) --details gparted details file path and name (default: ${DETAILS}) --compress compress new image (an extra file is generated) (default: ${COMPRESS}) --write write new image to SD card (default: ${WRITE}) --skip-read read image from SD card (false for an already existing image) (default: ${READ}) --skip-resize resize image with GParted (default: ${RESIZE}) --skip-fill fill empty space of new image with zeroes, only possible if RESIZE=true (default: ${FILL}) HEREDOC } function _parse { # Gather commands while (( "${#}" )) do case "${1}" in --user) USER="${2}" shift shift ;; --device) DEVICE="${2}" shift shift ;; --date_name) IMAGE_NAME="image_$(date +"%y%m%d%H%M%S")" shift ;; --image) IMAGE="${2}" shift shift ;; --details) DETAILS="${2}" shift shift ;; --skip-read) READ=false shift ;; --skip-resize) RESIZE=false shift ;; --skip-fill) FILL=false shift ;; --compress) COMPRESS=true shift ;; --write) WRITE=true shift ;; *|-*|--*=) # unsupported flags echo "Unknown ${1}" exit 1 ;; esac done } pause(){ printf "\n" printf "$1\n" read -p "press [Enter] to continue, CTRL-C to abort" key printf "\n" } checkDevice(){ if [ "$1" == "" -o "$(df -h --output=source | grep "$DEVICE")" == "" ]; then printf "device '$1' does not exist\n" printf "> check SD card devices with 'df -h'\n" printf "> re-insert SD card if necessary\n" printf "> edit DEVICE= in script if necessary\n\n" exit 1 fi } function _main { echo "shrink ${SHRINK_VERSION} qrt@qland.de" if [ $(id -u) -ne 0 ]; then printf "\n" printf "script must be run as root\n" printf "> try 'sudo ./shrink'\n\n" exit 1 fi if [ "$USER" == "" ]; then printf "\n" printf "user not set\n" printf "> edit USER= in script\n\n" exit 1 fi if [ $READ == true ]; then if [ -f $IMAGE ]; then pause "file '$IMAGE' already exists and will be overwritten" echo -ne '\033[1A' # one line up fi pause "insert source SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsizek=$(($(blockdev --getsize64 $DEVICE)/1024)) bsizem=$(($bsizek/1024)) freem=$((`df -k --output=avail "$PWD" | tail -n1`/1024)) if [ $freem -lt $(($bsizem*3)) ]; then pause "warning: free memory "$freem"M is possibly too low for image (+ zip)" echo -ne '\033[1A' # one line up fi sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "generate image from SD card" bsize=$bsizek"K" sudo dd if=$DEVICE status=none | pv -s $bsize | dd of=$IMAGE bs=4096 status=none \ && echo image read ok || exit 1 sudo sync pause "remove SD card" echo -ne '\033[1A' # one line up fi echo sudo chown $USER:$USER $IMAGE && echo owner and group ok || exit 1 if [ $RESIZE == true ]; then #sudo fdisk -l $IMAGE #read -p "enter Start of part 2: " start start="$(sudo parted $IMAGE -ms unit s print | grep "^2" | cut -f2 -d: | sed 's/[^0-9]*//g')" sudo losetup -d ${LOOP} >/dev/null 2>&1 # remove possible open loop sudo losetup ${LOOP} ${IMAGE} -o $((start*512)) && echo loop setup ok || exit 1 echo echo "GParted desktop is started now" echo "- go to GParted desktop window" echo "- select '$LOOP'" echo "- menu 'Partition / Resize/Move'" echo "- change value of 'New Size' about >= 250 MB above 'Minimum Size'" echo "- press button 'Resize/Move'" echo "- menu 'Edit / Apply All Operations' and press Apply" echo "- wait until GParted is ready - do not close dialog yet" echo "- press button 'Save Details' and 'Save' in file requester" echo " details are saved to $DETAILS" echo "- close dialog and exit GParted" echo rm -f ~/gparted_details.htm # remove old details sudo gparted $LOOP >/dev/null 2>&1 # supresses GLib messages if [ ! -f $DETAILS ]; then # check details exist echo "gparted details file not found" exit 1 fi size=$(awk '/resize2fs -p / {print $4;}' $DETAILS | awk 'BEGIN { FS="K"; } { print $1; }') rm -f ~/gparted_details.htm # remove details if [ -z $size ]; then # check size echo "size not found in details" exit 1 elif [ $size -lt 512000 ]; then echo "suspicious small filesize" exit 1 fi sudo losetup -d $LOOP && echo loop remove ok || exit 1 sudo losetup $LOOP $IMAGE && echo loop setup ok || exit 1 newsize="+${size}K" printf "d\n2\nn\np\n2\n$start\n$newsize\np\nw\n" | sudo fdisk $LOOP >/dev/null 2>&1 echo resize ok #sudo fdisk -l $LOOP #read -p "enter End of part 2: " end end="$(sudo parted $LOOP -ms unit s print | grep "^2" | cut -f3 -d: | sed 's/[^0-9]*//g')" sudo losetup -d $LOOP && echo loop remove ok || exit 1 truncate -s $(((end+1)*512)) $IMAGE && echo truncate ok || exit 1 if [ $FILL == true ]; then echo echo fill empty space sudo losetup $LOOP $IMAGE -o $((start*512)) sudo mkdir -p /mnt/imageroot sudo mount $LOOP /mnt/imageroot bsize="$(($(df -h -B1K | grep ^$LOOP | awk '{print $4}')*11/10))K" # +10% progress bar fs overhead correction sudo dd if=/dev/zero | pv -s $bsize | dd of=/mnt/imageroot/zero.txt >/dev/null 2>&1 sudo rm /mnt/imageroot/zero.txt sudo umount /mnt/imageroot sudo rmdir /mnt/imageroot sudo losetup -d $LOOP echo fill empty space ok fi fi if [ $COMPRESS == true ]; then echo echo compress image tar pcf - $IMAGE | pv -s $(du -sb $IMAGE | awk '{print $1}') | gzip > $IMAGE_NAME.tar.gz \ && echo compress ok || echo compress failed fi if [ $WRITE == true ]; then pause "insert target SD card and >>> close all popup file manager windows <<<" checkDevice $DEVICE bsize="$(($(blockdev --getsize64 $DEVICE)/1024))K" sudo umount $DEVICE?* && echo unmount ok || exit 1 echo echo "write image to SD card" sudo dd if=$IMAGE status=none | pv -s $bsize | dd of=$DEVICE bs=4096 status=none \ && echo image write ok || exit 1 sudo sync echo echo remove SD card fi echo echo ready echo } if [ "${1:-}" == -h ] || [ "${1:-}" == --help ]; then _print_help else # check script dependencies command -v gparted >/dev/null 2>&1 || { echo >&2 "Cannot locate gparted. Is it installed? Aborting."; exit 1; } command -v pv >/dev/null 2>&1 || { echo >&2 "Cannot locate pv. Is it installed? Aborting."; exit 1; } echo "calling parser" _parse "$@" _main "$@" fi