Mar 102013
 

There’s been a few threads recently on the Raspberry Pi forums regarding SD Card images too big to fit on other SD cards.
So I’ve come up with a script to automatically resize SD Cards to the smallest size possible. At the moment it is Linux only unfortunately, but I may release a windows version if there’s demand.

The script can be downloaded from here

or copied and pasted from here

#!/bin/bash
# Automatic Image file resizer
# Written by SirLagz
strImgFile=$1


if [[ ! $(whoami) =~ "root" ]]; then
echo ""
echo "**********************************"
echo "*** This should be run as root ***"
echo "**********************************"
echo ""
exit
fi

if [[ -z $1 ]]; then
echo "Usage: ./autosizer.sh "
exit
fi

if [[ ! -e $1 || ! $(file $1) =~ "x86" ]]; then
echo "Error : Not an image file, or file doesn't exist"
exit
fi

partinfo=`parted -m $1 unit B print`
partnumber=`echo "$partinfo" | grep ext4 | awk -F: ' { print $1 } '`
partstart=`echo "$partinfo" | grep ext4 | awk -F: ' { print substr($2,0,length($2)-1) } '`
loopback=`losetup -f --show -o $partstart $1`
e2fsck -f $loopback
minsize=`resize2fs -P $loopback | awk -F': ' ' { print $2 } '`
minsize=`echo $minsize+1000 | bc`
resize2fs -p $loopback $minsize
sleep 1
losetup -d $loopback
partnewsize=`echo "$minsize * 4096" | bc`
newpartend=`echo "$partstart + $partnewsize" | bc`
part1=`parted $1 rm 2`
part2=`parted $1 unit B mkpart primary $partstart $newpartend`
endresult=`parted -m $1 unit B print free | tail -1 | awk -F: ' { print substr($2,0,length($2)-1) } '`
truncate -s $endresult $1


Please support the continued development of any useful scripts and tutorials that you have found useful !




Share

  106 Responses to “Script : Automatic RPi Image Downsizer”

  1. great, just what I need. I was moving an image between 4GB cards today and was a few bytes short.

  2. Thanks for publishing this.
    I’d love to be able to use it. I tried using your script in a linux environment created from a bootable parted magic cd rom (image downloaded from partedmagic.com) but I was denied permission to run your script.

    I hope you had a lot of demand for a windows version and that you will be able to post it soon!
    In the meantime, I’ll try and understand how to get the right permissions. If so, I’ll post a new comment explaining it to your readers who may have the same problem.
    Thanks again
    Anne-Laure

  3. I managed to use your script on a windows computer :
    I booted the computer with a cd created with an image downloaded from partedmagic.com. I was then in a linux environment. I used the “default settings + language (french64) to get the right keyboard.
    I first could not run your script from the command line because permission was denied. With the help from http://forums.partedmagic.com/viewtopic.php?f=4&t=1696#p7159, I did the following :
    – transfer your script to the /etc directory, using the file manager
    – In the file manager, I selected the script and right clicked on it. I chose properties / root and put permissions on rwxrwxrwx.
    – In the command line I then typed cd /etc
    – I ran ././autosizer.sh path/filename

    It worked. I can now transfer the image from a 4 Gb sd card to another 4 Gb sd card which is slightly smaller. Thanks !
    The only problem with this is that I have to do it all each time. I will now have to understand how to create a linux partition on my laptop!
    Thanks again
    Anne-Laure

    • That’s great, thanks for providing all that information 🙂

      I’ve actually created the PiParted LiveCD which will eventually take over from this script for any newbies.
      The script is more for people who already have a linux distribution ready to go, and just need to resize an image file.

      The next version of PiParted should have this functionality built into it so keep your eyes peeled 🙂

  4. can you make a xp or win7 version? i very much need it.

    • I’ve had a look at the possibility, but decided that it is probably too hard to do that. The alternative is to use a livecd to run the script. I am also creating a livecd called PiParted which can resize images but it is not finished yet.

  5. Hi SirLagz,

    first thx for your script, but not worked 🙁 on my system (Debian Squeeze)

    the problem :

    command : partinfo=`parted -m $1 unit B print`

    result : BYT; /home/user/Bureau/wheezy-optimized-8GB-mini.img:7822376960B:file:512:512:msdos:; 1:4194304B:62914559B:58720256B:fat16::lba; 2:62914560B:7822376959B:7759462400B:ext4::;

    command : partstart=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)-1) } ‘`

    result : 6291456

    this result is wrong ! the good result is 62914560.
    i do not understand why my out of this command is different of your

    solution :

    partstart=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)) } ‘` —->>>> without -1

    parted –version : parted (GNU parted) 2.3

    can you send me a response of your command : partinfo=`parted -m $1 unit B print`

    maybe you can add this to your script (it’s not always an ext4 in the img …) :

    if [[ $partnumber == “” || ! “$partnumber” =~ ^[0-9]+$ ]]; then
    echo “Error : not contain filesystem ext4”
    exit
    fi

    • Perhaps parted’s formatting has changed. What version of parted are you using ?

      • parted –version : parted (GNU parted) 2.3

      • Hello,

        sorry to disturb you again …

        but i want understand why you script work on your linux and not on my debian linux.
        I think the difference is in the function substr of the awk command

        echo | awk ‘{print substr(“12345678B”, 0, 5)}’ ——>>> 1234
        echo | awk ‘{print substr(“12345678B”, 1, 5)}’ ——>>> 12345

        so if i start position on 1 the result of your script is good.
        can you test plz on your machine 🙂

  6. final version :

    #!/bin/bash
    # Automatic Image file resizer
    # Written by SirLagz
    strImgFile=$1

    export PATH=$PATH:/sbin

    if [[ ! $(whoami) =~ “root” ]]; then
    echo “”
    echo “**********************************”
    echo “*** This should be run as root ***”
    echo “**********************************”
    echo “”
    exit
    fi

    if [[ -z $1 ]]; then
    echo “Usage: ./autosizer.sh ”
    exit
    fi

    if [[ ! -e $1 || ! $(file $1) =~ “x86” ]]; then
    echo “Error : Not an image file, or file doesn’t exist”
    exit
    fi

    partinfo=`parted -ms $1 unit B p`
    existRootPart=`echo “$partinfo” | grep -o ‘B:ext4:\|B:ext3:’`
    numberOfMatchPart=`echo “$existRootPart” | wc -l`

    if [[ $existRootPart == “” || $numberOfMatchPart -eq 0 || $numberOfMatchPart -gt 1 ]] ; then
    echo “Error : Your partition layout is not currently supported by this tool.”
    exit
    fi

    fileSystemType=`echo “$existRootPart” | cut -d: -f2`
    partnumber=`echo “$partinfo” | grep $fileSystemType | awk -F: ‘ { print $1 } ‘`
    partstart=`echo “$partinfo” | grep $fileSystemType | awk -F: ‘ { print substr($2,0,length($2)) } ‘`
    loopback=`losetup -f –show -o $partstart $1`

    e2fsck -f $loopback

    minsize=`resize2fs -P $loopback | awk -F’: ‘ ‘ { print $2 } ‘`
    minsize=`echo $minsize+1000 | bc`

    resize2fs -p $loopback $minsize
    sleep 1
    losetup -d $loopback

    partnewsize=`echo “$minsize * 4096” | bc`
    newpartend=`echo “$partstart + $partnewsize” | bc`

    parted $1 rm $partnumber
    parted $1 unit B mkpart primary $partstart $newpartend
    endresult=`parted -m $1 unit B print free | tail -1 | awk -F: ‘ { print substr($2,0,length($2)) } ‘`
    truncate -s $endresult $1

  7. unfortunatly it doesn’t work for me 🙁

    Now I see the error:
    losetup: invalid offset ‘PMATIC_RPi_2014-01-05.img’ specified
    and many other errors later. How to fix it?

  8. […] size differences here. I tried shrinking the image with a utility I use for Raspbian images – autosizer.sh, by SirLagz but that didn’t work (probably due to the unusual partition arrangement). I didn’t have […]

  9. Great script, worked out of the box, here.

    Found one problem. It reduces partition size to absolute min. I had an image that I wanted to make changes to, before expanding, so I made a change to minsize to allow about 10% free blocks.

    Here’s the modified script:

    #!/bin/bash
    # Automatic Image file resizer
    # Written by SirLagz
    strImgFile=$1

    if [[ ! $(whoami) =~ “root” ]]; then
    echo “”
    echo “**********************************”
    echo “*** This should be run as root ***”
    echo “**********************************”
    echo “”
    exit
    fi

    if [[ -z $1 ]]; then
    echo “Usage: ./autosizer.sh ”
    exit
    fi

    if [[ ! -e $1 || ! $(file $1) =~ “x86” ]]; then
    echo “Error : Not an image file, or file doesn’t exist”
    exit
    fi

    partinfo=`parted -m $1 unit B print`
    partnumber=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print $1 } ‘`
    partstart=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)-1) } ‘`
    loopback=`losetup -f –show -o $partstart $1`
    e2fsck -f $loopback
    minsize=`resize2fs -P $loopback | awk -F’: ‘ ‘ { print $2 } ‘`

    # Modified minsize calc by Kevin Rattai
    #
    # original minsize produces 0bytes on partition, calculated as:
    # minsize=`echo “$minsize+1000” | bc`
    #
    # New minsize calc produces 10% minsize as available space
    minsize=`echo “($minsize+($minsize*0.1))/1” | bc`

    resize2fs -p $loopback $minsize
    sleep 1
    losetup -d $loopback
    partnewsize=`echo “$minsize * 4096” | bc`
    newpartend=`echo “$partstart + $partnewsize” | bc`
    part1=`parted $1 rm 2`
    part2=`parted $1 unit B mkpart primary $partstart $newpartend`
    endresult=`parted -m $1 unit B print free | tail -1 | awk -F: ‘ { print substr($2,0,length($2)-1) } ‘`
    truncate -s $endresult $1

  10. Autosizer.sh is a Great tool, working like a charm.
    Downsized a 32GB sd to 2.5 GB……

    Looking forward to the PiParted issued with this tool
    Or did I miss an update ? 🙂

    http://sirlagz.net/2013/04/02/896/

    • Never got around to including it on PiParted.

      There’s much less demand for a tool like PiParted now with NOOBS and the like making it easier for newbies to get started.

  11. When I try to run it, i get a message saying

    -bash: ./autosizer.sh: Permission denied

    Am I doing it right? What I did was:

    pi@raspberrypi ~ $ sudo nano autosizer.sh

    Then I copyed Kevin Rettal’s modified script, saved it but when I run it using:

    pi@raspberrypi ~ $ sudo bash autosizer.sh

    This message comes up
    “Usage: ./autosizer.sh ”

    What do I do?

    • I don’t get the
      “-bash: ./autosizer.sh: Permission denied” anymore but it still keeps saying “Usage: ./autosizer.sh”

    • Try this command first
      sudo su
      This will change the user to root so you will not encounter any permission errors under root user without putting sudo first each time and extra functionality that sudo might not provide.
      Then run the script ./autosizer.sh image.img where image.img is existing file in the same directory as autosizer.sh script

  12. Pfew, this script saved me a whole lot of trouble today !

    I wanted to clone a customized Raspbian on a 64 GB microSD, but the new one was a few sectors short…

    Fortunately it was far from full and your script made a smaller one, worked like a champ right away !

    Thanks a lot for this very useful tool,
    fp

  13. Thanks! Worked like a charm! Had to comment out the exit at image check it was failing that check.

    echo “Error : Not an image file, or file doesn’t exist”
    #exit

    Took a 7.5gb image down to 2.5gb!

  14. Is this script supposed to work on a NOOBS image? If I use it I get a smaller .img, but it doesn’t boot.
    Kind regards,
    BB

  15. Hi,

    nice script, but I had a little problem. Even though I tried to downsize a normal raspbian image created with dd I always got the message:
    “Error : Not an image file, or file doesn’t exist”
    So I looked at the output of
    file /path/to/img
    /path/to/img: ; partition 1: ID=0xc, starthead 130, startsector 8192, 114688 sectors; partition 2: ID=0x83, starthead 165, startsector 122880, 2424809 sectors
    So I changed if [[ ! -e $1 || ! $(file $1) =~ "x86" ]]; then
    to if [[ ! -e $1 || ! $(file $1) =~ "x83" ]]; then

  16. Hi, I´m a noob when it comes to linux systems, can this script be run on the raspberry directly?

  17. Sorry, I would dearly like to use this script but I still am not sure how it operates.
    What does it take for input: an SDcard or an image file of the SDcard?
    Do I need to specify the input and output when giving the command ./autosizer.sh ?

  18. I´m trying to use this script on the image found here:
    http://www.instructables.com/id/MAME-gaming-table-with-Raspberry-Pi/?ALLSTEPS

    Problem is that I dont have any ext4 partinfo.
    parted gives me: pimame.img:3980394496B:file:512:512:msdos:;
    1:4194304B:62914559B:58720256B:fat16::lba;

    Why is this and is there a workaround to get it to work?

  19. […] Read the image with win32 disk imager, copy to VM in ubuntu and try to resize using this script http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/. […]

  20. Sorry but I have tried out all comments and modifications on Ubuntu for a bananaPi image file of 32GB, which I wanted to reduce but nothing worked.
    Awk seems to give alot of syntax errors and so I am lost.
    Did anyone find another solution to reduce the size ??
    greetings
    felix

  21. Thanks for the script!

    I tried it on ubuntu 14.04 when trying to reduce an image file created with dd (bs=4). First I get a ext2fs_open2: Bad magic number in super-block, then e2fsck: superblock invalid, trying backup blocks… then e2fsck: Bad magic number in super-block while trying to open /dev/loop0.

    Finally: The superblock could not be read or does not describe a valid ext2/ext3/ext4 filesystem. This could be because the first filesystem is MSDOS (FAT16 or32?). Then it continues with the second filesystem (I guess). and now I get the following:
    resize2fs: Bad magic number in super-block while trying to open /dev/loop0
    (standard_in) 1: syntax error
    resize2fs: Bad magic number in super-block while trying to open /dev/loop0 (twice thus!)
    Couldn’t find valid filesystem superblock
    (standard_in) 1: syntax error
    (standard_in 2: syntax error.

    And now it hangs sort of (I have been waiting for 10 minutes). Any suggestions?

    • NiceGuy,

      I’m facing same problem as you do. Did get a solution for this?

      • I’ll have a look at the script. If the partition layout has changed then this script may not work anymore.

        I’ll post an update when I have had a look.

        • Hi,
          Same here…

          First I got “Not an image file, or file doesn’t exist”
          then if I comment out the file test, I got the same magic number errors as NiceGuy above….

          Here my fdisk -l

          Disk /dev/mmcblk0: 31.6 GB, 31637635072 bytes
          4 heads, 16 sectors/track, 965504 cylinders, total 61792256 sectors
          Units = sectors of 1 * 512 = 512 bytes
          Sector size (logical/physical): 512 bytes / 512 bytes
          I/O size (minimum/optimal): 512 bytes / 512 bytes
          Disk identifier: 0x000c45c9

          Device Boot Start End Blocks Id System
          /dev/mmcblk0p1 8192 122879 57344 c W95 FAT32 (LBA)
          /dev/mmcblk0p2 122880 61792255 30834688 83 Linux

          Imagefile produced with win32 disk imager

          Is there any solution/workaround?
          Thanks a lot for your effort!

  22. I think I crashed my sd card with this method? 😉 i have an bootloop with this error. Does anyone have an idea for a solution?
    Fotos:
    http://1drv.ms/1EkLcC2]http://1drv.ms/1EkLcC2

  23. Edit Link just ine time: http://1drv.ms/1EkLcC2

  24. Hi,
    tried the script to reduce a 16GB image file to fit on a 8GB. I dont get any errors, but the script seems to hang
    e2fsck 1.42.9 (4-Feb-2014)
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    /dev/loop0: 5571/1761280 files (0.8% non-contiguous), 771893/7038800 blocks
    resize2fs 1.42.9 (4-Feb-2014)
    resize2fs 1.42.9 (4-Feb-2014)
    Resizing the filesystem on /dev/loop0 to 587887 (1k) blocks.
    Begin pass 2 (max = 46848)
    Relocating blocks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 3 (max = 860)
    Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 4 (max = 1014)
    Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/loop0 is now 587887 blocks long.

    There is still disk access, but I have been waiting > 5mins. Any suggestions?

    • If the filesystem is updated then it should be fine.
      Just make sure that any references to the loop devices are gone before you try and write the image to a SD card

      • I’m stuck in the same problem (same Ubuntu version): your script runs without any erron till it hungs on “The filesystem on /dev/loop0 is now 1786237 blocks long.” line.
        But if i check the size of the image file, i find it is still the old size, not 1786 MB. Can you help us?

  25. Big Thank You to SirLagz,
    this script is great and safed me a lot of time.

    I changed the script a little bit to make it easier to execute with sudo and autopack the image after resizing.
    It uses pv to show the progress.

    #!/bin/bash
    # Automatic Image file resizer
    # Written by SirLagz

    if [[ $EUID -ne 0 ]]; then
    echo “”
    echo “***********************************”
    echo “** Needs to be run as super user **”
    echo “***********************************”
    echo “”
    exit
    fi

    if [[ -z $1 ]]; then
    echo “Usage: $0 ”
    exit
    fi

    if [[ ! -e $1 || ! $(file $1) =~ “x86” ]]; then
    echo “Error : Not an image file, or file doesn’t exist”
    exit
    fi

    partinfo=`parted -m $1 unit B print`
    partnumber=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print $1 } ‘`
    partstart=`echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)) } ‘`
    loopback=`losetup -f –show -o $partstart $1`
    e2fsck -f $loopback
    minsize=`resize2fs -P $loopback | awk -F’: ‘ ‘ { print $2 } ‘`
    minsize=`echo $minsize+1000 | bc`
    resize2fs -p $loopback $minsize
    sleep 1
    losetup -d $loopback
    partnewsize=`echo “$minsize * 4096” | bc`
    newpartend=`echo “$partstart + $partnewsize” | bc`
    part1=`parted $1 rm 2`
    part2=`parted $1 unit B mkpart primary $partstart $newpartend`
    endresult=`parted -m $1 unit B print free | tail -1 | awk -F: ‘ { print substr($2,0,length($2)) } ‘`
    truncate -s $endresult $1

    read -p”Pack image (y/n)? ” response
    if [ “$response” == “y” ]; then
    filename=”$1.gz”
    if [ -f “$filename” ]; then
    read -p”File already exists. Replace (y/n)? ” response
    if [ “$response” == “n” ]; then
    read -p”Enter new name: ” response
    filename=”$response.img.gz”
    fi
    fi
    pv $1 | gzip > $filename
    chown $SUDO_USER:$SUDO_USER $filename
    read -p”Delete unpacked image (y/n)? ” response
    if [ “$response” == “y” ]; then
    rm $1
    fi
    fi

  26. hi. sorry i am lost. do i have to run this in my raspberry or in my debian box?

  27. Please be careful with this script, it destroyed two of my images.

    Make backup copies before running it.

    • Were the images using the default partition layout?
      I haven’t had any issues with the script so far but it’s been a while since I’ve used it. I’ll try and test with some up to date images and see if I find any issues.

  28. Just of note, if the resize2fs program returns “Please run ‘e2fsck -f /dev/loop0’ first” it will still go through and truncate the image, but the partition won’t be resized correctly.

    You might want to have the script check for this, otherwise the image will be corrupt. In the meantime, you can use the -f option on the second resize2fs command so it will force it to run.

  29. This was so helpful for me, thanks alot for making and publishing this script.
    one more question, is it possible to control size of output image file? i mean is it possible to instruct the script to produce output not more than 8 G for instance.

    • I didn’t code my script that way, but if you write the small image to an 8GB SD card, you can then resize the partition and filesystem to fill the 8GB card quite easily

  30. Hi,
    I’m a super basic user and i have a 8GB Debian image which i want to reduce.
    I have a mac and will install a virtual ubuntu on it.
    Could you please advice on how to run this script in a very basic steps.

    Many thanks in advance

    • If you have the image, you just run the script like so:
      /path/to/script.sh /path/to/file.img

      • tried to run it just to see the response w/o the path to the image file but I cant get it to work

        the script is named autosizer.sh and it is in this folder:
        /home/Franz/Downloads/SD-Card_autodownsizer-scrips/original

        I tried this command:
        sudo /home/Franz/Downloads/SD-Card_autodownsizer-scripts/original/autosizer.sh

        I get the message:
        sudo: /home/Franz/Downloads/SD-Card_autodownsizer-scripts/original/autosizer: command not found

        I also tried
        sudo /home/Franz/Downloads/SD-Card_autodownsizer-scripts/original/autosizer

        same result

        I also wonder if once I get it running I’d be to change the name

        • You may not have the commands that the autosizer script requires. Things like bc may not be installed on your system.

  31. Hi,
    just tried the script to reduce an image from a 16Gb card.

    i coped the image to a file pi16gb.img and then from the same folder ran
    ./autosizer.sh pi16gb.img
    to reduce the size.

    I then copied the image with
    dd bs=1M if=pi16gb.img of=/dev/sdb

    no errors reported at any stage, when i put the new card into my PI i get an error
    “kernal panic not syncing unable to mount fs on unknown block

    any idea what I have done wrong?
    I can’t see anywhere obvious ( to me ) in the script where a new file is created
    should I use bs=4M?
    I am going to try that next.

  32. SirLagz, I am also getting the “Bad Magic Number in super-block” error. I am also getting “bc: command not found.”

    Thanks so much for your work on this script in the past, I hope you are going to rewrite it soon – it seems like it could be very helpful for transferring images.

    • Getting ‘bc: command not found’ means that the ‘bc’ utility is not installed. I’ll look at rewriting the tool so that it doesn’t rely on external utilities when I have some free time.

      • where and how to get bc?

        i got the same error too as seen below:

        pi@rMirror:/media/pi/untitled $ sudo ./autosizer.sh gmail.img
        e2fsck 1.42.12 (29-Aug-2014)
        ext2fs_open2: Bad magic number in super-block
        e2fsck: Superblock invalid, trying backup blocks…
        e2fsck: Bad magic number in super-block while trying to open /dev/loop0

        The superblock could not be read or does not describe a valid ext2/ext3/ext4
        filesystem. If the device is valid and it really contains an ext2/ext3/ext4
        filesystem (and not swap or ufs or something else), then the superblock
        is corrupt, and you might try running e2fsck with an alternate superblock:
        e2fsck -b 8193
        or
        e2fsck -b 32768

        resize2fs 1.42.12 (29-Aug-2014)
        resize2fs: Bad magic number in super-block while trying to open /dev/loop0
        ./autosizer.sh: line 31: bc: command not found
        resize2fs 1.42.12 (29-Aug-2014)
        resize2fs: Bad magic number in super-block while trying to open /dev/loop0
        Couldn’t find valid filesystem superblock.
        ./autosizer.sh: line 35: bc: command not found
        ./autosizer.sh: line 36: bc: command not found

  33. I run the command ./autosizer.sh Image_pi2.img and the result is:
    Error. Not an image file, or file does not exist.

  34. Thanks posting this and all the follow-up work. Your script was the game-winning end-note on a couple of frustrating hours of trying to get the “2016-02-09-raspbian-jessie” image onto my 4gb cards for a class in the morning. Amazing what a couple of well written lines of code can do for you.

  35. Tried it just now and it seemed to have worked like a charm.
    Haven’t tried the resulting image yet, but the script ran great out of the box on my Xubuntu 14.04 laptop.

  36. Can you please provide the latest version of your script? I keep getting this errors on Ubuntu 12.04:
    awk: 1: unexpected character 0xe2
    ./autosizer.sh: command substitution: line 26: syntax error near unexpected token `(‘
    ./autosizer.sh: command substitution: line 26: `echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)) } ‘’
    losetup: invalid offset ‘test1.img’ specified

    Usage:
    losetup loop_device give info
    losetup -a | –all list all used
    losetup -d | –detach [ …] delete
    losetup -f | –find find unused
    losetup -c | –set-capacity resize
    losetup -j | –associated [-o ] list all associated with
    losetup [options] {-f|–find|loopdev} setup

    Options:
    -e, –encryption enable data encryption with specified
    -h, –help this help
    -o, –offset start at offset into file
    –sizelimit loop limited to only bytes of the file
    -p, –pass-fd read passphrase from file descriptor
    -r, –read-only setup read-only loop device
    –show print device name (with -f )
    -N | –nohashpass Do not hash the given password (Debian hashes)
    -k | –keybits specify number of bits in the hashed key given
    to the cipher. Some ciphers support several key
    sizes and might be more efficient with a smaller
    key size. Key sizes < 128 are generally not
    recommended
    -v, –verbose verbose mode

    Usage: e2fsck [-panyrcdfvtDFV] [-b superblock] [-B blocksize]
    [-I inode_buffer_blocks] [-P process_inode_size]
    [-l|-L bad_blocks_file] [-C fd] [-j external_journal]
    [-E extended-options] device

    Emergency help:
    -p Automatic repair (no questions)
    -n Make no changes to the filesystem
    -y Assume "yes" to all questions
    -c Check for bad blocks and add them to the badblock list
    -f Force checking even if filesystem is marked clean
    -v Be verbose
    -b superblock Use alternative superblock
    -B blocksize Force blocksize when looking for superblock
    -j external_journal Set location of the external journal
    -l bad_blocks_file Add to badblocks list
    -L bad_blocks_file Set badblocks list
    awk: 1: resize2fs 1.42 (29-Nov-2011)
    unexpected character 0xe2
    Usage: resize2fs [-d debug_flags] [-f] [-F] [-M] [-P] [-p] device [new_size]

    (standard_in) 1: syntax error
    resize2fs 1.42 (29-Nov-2011)
    Usage: resize2fs [-d debug_flags] [-f] [-F] [-M] [-P] [-p] device [new_size]

    Usage:
    losetup loop_device give info
    losetup -a | –all list all used
    losetup -d | –detach [ …] delete
    losetup -f | –find find unused
    losetup -c | –set-capacity resize
    losetup -j | –associated [-o ] list all associated with
    losetup [options] {-f|–find|loopdev} setup

    Options:
    -e, –encryption enable data encryption with specified
    -h, –help this help
    -o, –offset start at offset into file
    –sizelimit loop limited to only bytes of the file
    -p, –pass-fd read passphrase from file descriptor
    -r, –read-only setup read-only loop device
    –show print device name (with -f )
    -N | –nohashpass Do not hash the given password (Debian hashes)
    -k | –keybits specify number of bits in the hashed key given
    to the cipher. Some ciphers support several key
    sizes and might be more efficient with a smaller
    key size. Key sizes < 128 are generally not
    recommended
    -v, –verbose verbose mode

    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \234
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: ~
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: J
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: I
    (standard_in) 1: illegal character: P
    (standard_in) 1: illegal character: S
    (standard_in) 1: illegal character: S
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: I
    (standard_in) 1: illegal character: X
    (standard_in) 1: illegal character: W
    (standard_in) 1: illegal character: M
    (standard_in) 1: illegal character: S
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: I
    (standard_in) 1: illegal character: T
    (standard_in) 1: illegal character: R
    (standard_in) 1: illegal character: L
    (standard_in) 1: illegal character: S
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: T
    (standard_in) 1: illegal character: R
    (standard_in) 1: illegal character: I
    (standard_in) 1: illegal character: X
    (standard_in) 1: illegal character: W
    (standard_in) 1: illegal character: M
    (standard_in) 1: illegal character: S
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: I
    (standard_in) 1: illegal character: T
    (standard_in) 1: illegal character: R
    (standard_in) 1: illegal character: L
    (standard_in) 1: illegal character: S
    (standard_in) 1: illegal character: _
    (standard_in) 1: illegal character: T
    (standard_in) 1: illegal character: R
    (standard_in) 1: illegal character: _
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: Q
    (standard_in) 1: illegal character: K
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: Q
    (standard_in) 1: illegal character: K
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: K
    (standard_in) 1: illegal character: K
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: N
    (standard_in) 1: illegal character: N
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: U
    (standard_in) 1: illegal character: ~
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \235
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \234
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \235

  37. Hi – Thanks for the script it works great with my Raspbian images saved with Win32DiskImager.

    Now I’m trying to get it to work with an image taken from a Raspberry Pi Compute Module using DD.

    I’ve saved the image with dd ( and verified I can write it back to the compute module with dd and boot ), and when I run autosized.sh on it I get the following error:

    sudo ./autosizer.sh 2016-03-11-My.img
    Error : Not an image file, or file doesn’t exist

    In the script, it is looking for an ‘x86’ type image.

    When I run file, I get this:

    me@ubuntu:~/Desktop$ file 2016-03-11-My.img
    2016-03-11-My.img: ; partition 1 : ID=0xc, start-CHS (0x0,130,3), end-CHS (0x7,165,30), startsector 8192, 114688 sectors

    How can I get this to work with the compute module image? Thanks!

  38. […] Special thanks to SirLagz for making this SD Card downsizer script that saved me time: http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/ […]

  39. SirLagz,

    Thanks for your work on this script!

    I’m having a problem and could use your advice.

    I created a new Raspbian Jesse image, did all the updates and customization that I wanted, and confirmed its operation.

    I booted my Pi3 from a different SD Card, attached a USB Card Reader and did a ‘sudo dd if=/dev/sda of=/home/pi/tmp/ADevPiSignage3.img’

    The first time I ran your script I got the following”
    ./autosizer.sh /home/pi/tmp/ADevPiSignage3.img
    “Error : Not an image file, or file doesn’t exist”

    So, seeing what others have done here, I commented out the ‘exit’ and tried again. Here’s the output from the 2nd try:

    “Error : Not an image file, or file doesn’t exist”
    awk: 1: unexpected character 0xe2
    ./autosizer.sh: command substitution: line 26: syntax error near unexpected token `(‘
    ./autosizer.sh: command substitution: line 26: `echo “$partinfo” | grep ext4 | awk -F: ‘ { print substr($2,0,length($2)) } ‘’
    losetup: failed to parse offset: ‘/home/pi/tmp/ADevPiSignage3.img’
    Usage: e2fsck [-panyrcdfvtDFV] [-b superblock] [-B blocksize]
    [-I inode_buffer_blocks] [-P process_inode_size]
    [-l|-L bad_blocks_file] [-C fd] [-j external_journal]
    [-E extended-options] device

    Emergency help:
    -p Automatic repair (no questions)
    -n Make no changes to the filesystem
    -y Assume “yes” to all questions
    -c Check for bad blocks and add them to the badblock list
    -f Force checking even if filesystem is marked clean
    -v Be verbose
    -b superblock Use alternative superblock
    -B blocksize Force blocksize when looking for superblock
    -j external_journal Set location of the external journal
    -l bad_blocks_file Add to badblocks list
    -L bad_blocks_file Set badblocks list
    awk: 1: unexpected character 0xe2
    resize2fs 1.42.12 (29-Aug-2014)
    Usage: resize2fs [-d debug_flags] [-f] [-F] [-M] [-P] [-p] device [new_size]

    (standard_in) 1: syntax error
    resize2fs 1.42.12 (29-Aug-2014)
    Usage: resize2fs [-d debug_flags] [-f] [-F] [-M] [-P] [-p] device [new_size]

    losetup: option requires an argument — ‘d’

    Usage:
    losetup [options] []
    losetup [options] -f |

    Options:
    -a, –all list all used devices
    -d, –detach … detach one or more devices
    -D, –detach-all detach all used devices
    -f, –find find first unused device
    -c, –set-capacity resize the device
    -j, –associated list all devices associated with

    -o, –offset start at offset into file
    –sizelimit device is limited to bytes of the file
    -P, –partscan create a partitioned loop device
    -r, –read-only set up a read-only loop device
    –show print device name after setup (with -f)
    -v, –verbose verbose mode

    -l, –list list info about all or specified (default)
    -O, –output specify columns to output for –list
    -n, –noheadings don’t print headings for –list output
    –raw use raw –list output format

    -h, –help display this help and exit
    -V, –version output version information and exit

    Available –list columns:
    NAME loop device name
    AUTOCLEAR autoclear flag set
    BACK-FILE device backing file
    BACK-INO backing file inode number
    BACK-MAJ:MIN backing file major:minor device number
    MAJ:MIN loop device major:minor number
    OFFSET offset from the beginning
    PARTSCAN partscan flag set
    RO read-only device
    SIZELIMIT size limit of the file in bytes

    For more details see losetup(8).
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \234
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \235
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \234
    (standard_in) 1: syntax error
    (standard_in) 1: illegal character: \342
    (standard_in) 1: illegal character: \200
    (standard_in) 1: illegal character: \235
    Error: Partition doesn’t exist.

    It was stalled there so I did a CTRL-C

    When I do a ‘ fdisk -l ADevPiSignage3.img’ I get the following:

    Disk ADevPiSignage3.img: 7.4 GiB, 7969177600 bytes, 15564800 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x95ebd19f

    Device Boot Start End Sectors Size Id Type
    ADevPiSignage3.img1 8192 131071 122880 60M c W95 FAT32 (LBA)

    Can you help?

    • You might need to do what Beldon Fox suggested and change awk to use a 1 as a starting point rather than a 0.

  40. First off, thanks so much for the script! Just what I was looking for.

    I, too, ran into problems running this on my Ubuntu distro. I tracked the problem down to the awk substr() calls you use to strip the ‘B’ off the end of numbers. The substr() call in awk uses 1-based indexing, not 0-based, so the second argument in each substr call should be 1, not 0.

    I ran some tests and it seems that awk enters undefined territory when you pass 0 for the starting index to substr. On Mac OS X substr(“Hello”, 0, 5) will return “Hello”. On Ubuntu substr(“Hello”, 0, 5) will return “Hell” which is only four bytes long. Changing the 0 to 1 produces identical (and correct) output on all distros.

    • Thanks for that! I’ll need to make sure I rewrite this script to be more distro friendly in the near future 🙂

    • Spot on!

      I used the script with Ubuntu to shrink a Raspbian image that wouldn’t fit inside an sd card although it was the same brand and same size of the original card.

      Changing the substr() calls in awk to use index 1 instead of 0 in the second argument did the trick for me!

      I’ll keep the script for future use!

      All the best!

  41. This is pretty old but I’d suggest changing this line

    echo “Usage: ./autosizer.sh ”

    to

    echo “Usage: ./autosizer.sh /path/to/pi.img file “

  42. my PI image not reduced, I got the below result when i ran the script.. with substr() function changes (0 to 1).

    ./autosizer.sh raspberry_pi_32g.img
    e2fsck 1.42.9 (4-Feb-2014)
    SETTINGS: recovering journal
    Pass 1: Checking inodes, blocks, and sizes
    Pass 2: Checking directory structure
    Pass 3: Checking directory connectivity
    Pass 4: Checking reference counts
    Pass 5: Checking group summary information
    SETTINGS: 40/8192 files (0.0% non-contiguous), 5579/32768 blocks
    resize2fs 1.42.9 (4-Feb-2014)
    resize2fs 1.42.9 (4-Feb-2014)
    Resizing the filesystem on /dev/loop0 to 9822 (1k) blocks.
    Begin pass 2 (max = 4096)
    Relocating blocks XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 3 (max = 4)
    Scanning inode table XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Begin pass 4 (max = 32)
    Updating inode references XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    The filesystem on /dev/loop0 is now 9822 blocks long.

    does it create new image file or it modifies(replaces) existing one..?

  43. Well done script.
    I add it to my crontab backup of my pi to save space.
    It’s a dd backup, followed by autosizer part and finally gzip of the img. With this script, I create 3G backup.img.gz of a 16G SD-card with a bit more than 6G used.

    There is a second nice result by using autosizer. Due to, I create my backup on running pi, the 2nd partition has a bug. Autosizer part repairs it. 🙂
    Many Thanks to you, SirLagz

  44. Hello,

    Many thanks SirLagz, for sharing this with the world.
    It works fine except for a strange issue I cant explain.
    I have to power cycle twice the Pi before it boots properly with the shrunk image.

    I have provided more details on this issue on the raspberrypi foundation forum :
    https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=165640

    Any clue ?

    Regards,

    Mohamed

    The

  45. ok guys, I have no idea how to run this script

    I believe to be in the root directory as ls provides this feedback:
    autosizer.sh boot etc lib media opt root run …..

    however if I execute
    /autosizer.sh image.img

    I get
    *** this should be run as root ***

    any idea how to get this script running?

  46. ok, I moved both files to
    /home/bfa1155/Documents

    then I changed the first line of the autosizer.sh to
    if [[ $EUID -ne 0 ]]; then

    and now I get
    ./autosizer.sh: line 1: #!/bin/bash: No such file or directory
    Error : Not an image file, or file doesn’t exist

  47. forgot to add that image.img shows as 16.0 GB Raw disk image in Caja file explorer

  48. Another (manual) method.
    I tried everything suggested here but could not get this to work.
    Frustrated a went back to web searching. I found this process that worked first time. Yes it is manual and you will need to make a note of a couple of numbers but IT WORKS.

    http://www.aoakley.com/articles/2015-10-09-resizing-sd-images.php

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)