At any one time I might have 3-4 Raspberry Pi projects going at once, but only 2 SD cards. Because of this, I use Win32 Disk Imager (the same program you probably used to write the Rasbian image to an SD card) to create images of the SD cards, which I keep on my backup drive. When I want to work on a project, I just image it back on the SD card.
This system works, however, over time those image files can add up. Each one is the same size as your SD card, so an 8 gig SD card generates an 8 gigabyte image. Not only can they start to fill up your hard drive, but if you store them on a network, it can take a long time to transfer them.
This command fills up the SD card’s free space with a huge file full of zeros and then deletes it. A long string of zeros is much easier to compress than a bunch of one’s and zero’s.
Compressing them in a zip file works, however, my zip files were still nearly 80% of the size of the original which didn’t offset the hassle of compressing and decompressing.
But then I discovered a method that compressed one of my images from 8 gigs down to just 125 megabytes. That’s a compression ratio of 1:34,359,738!
First I will explain what to do, then I will tell you why it works.
Open up a terminal window and execute this command:
cat /dev/zero > zeros || rm zeros
After a while this will appear:
cat: write error: No space left on device
That means you finished! You can now shut down your RasPi and compress it.
Here is what this command does:
- cat /dev/zero – cat is a program that concatenates. According to Wikipedia, “concatenation is the operation of joining character strings end-to-end”. In this case, cat is stringing /dev/zero end to end, outputting an endless string of zeros.
- > zeros – The less than sign is a redirection operator. It redirects the output of a command to somewhere else. In this case, output that was being sent to the screen (stdout) has been redirected to a file called zeros. In our case, this will continue until the zero file fills up the free space on the SD card at which point an error will occur and it will stop.
- || – This tells the computer what to do if the previous command “returns a non-zero exit status” AKA, if the previous command ends with an error. In our case the desired outcome is that the cat command end in an error, since we want it to only stop once there is no more room on the drive left, causing write error. The opposite of || is &&, which means if the first command is successful, run the next one.
- rm zeros – This deletes the file that filled up the free space, giving you space back on your SD card.
If you want to learn even more about this command, check out its explanation at explainshell.com.
Why does this save space? One way that file compressors squeeze files is by finding repeated data and encoding it. For example, “00000…” may be represented by “Zero 6515 times”.
When you make an image of an SD card, it doesn’t look a the file system, instead it copies the entire card bit by bit – ignoring whether or not that bit was part of a file or simply empty space. SD cards, even new ones, can be full of random data that is hard to compress. By converting all unused space to zeros, the file compressor will have a much easier time compressing your image.
One more tip, the cat command doesn’t have a progress bar, so you won’t know how far along you are. Instead, what you can do is open another terminal window and execute this command:
watch df -h
Watch is a program that watches output from other programs. In this case, watch will run the df -h command every two seconds refresh your screen with updated information. This way you can watch your SD card fill up until it reaches 100%: