Verifying a zeroed disk with zerocheck.sh #

UPDATE: While this was obviously never meant as a thorough check, I have now seen too many instances of partially-erased drives (like this one) to rely on it at all. Please see Verify disk wipe instead.

While you can verify a zero-filled disk with hexdump (among other tools), it takes many hours on large-capacity drives. I cobbled together a bash script to quickly check a user-defined number of megabytes from the beginning, middle, and end of a disk for zeros. Here's what it looks like when run under OS X (disk 0 and 1 details have been truncated):

    $ sudo zerocheck.sh

    zerocheck.sh - check disk for zeros

    /dev/disk0
    ...
    /dev/disk1
    ...
    /dev/disk2
       #:                       TYPE NAME                    SIZE       IDENTIFIER
       0:                                                   *500.1 GB   disk2

    Enter disk to check (e.g., /dev/disk2)
    /dev/disk2

    How many megabytes to check from the beginning, middle, and end of the disk?
    1

    /dev/disk2 has 500107862016 bytes.

    The first 1048576 bytes:
    0000000    000000  000000  000000  000000  000000  000000  000000  000000
    *
    1048576

    1048576 bytes from the middle:
    250053931008    000000  000000  000000  000000  000000  000000  000000  000000
    *
    250054979584

    And the final 1048576 bytes:
    500106813440    000000  000000  000000  000000  000000  000000  000000  000000
    *
    500107862016

There are two versions of the script. One for OS X:

#!/bin/bash

# zerocheck.sh - check the beginning, middle, and end of a drive for zeros.
# "when you don't have the time or interest for a full hexdump"

# tested under:
# mac os x 10.6 - 10.10

echo -e "\nzerocheck.sh - check disk for zeros\n"

# check os, display block devices, assign user's choice to variable "DISK2CHK"
if [ "$(uname)" == "Darwin" ]; then
    diskutil list
    echo "Enter disk to check (e.g., /dev/disk2)"
    read DISK2CHK
else
    echo "This script has only been tested under OS X."
    exit 1
fi

# ask for MBs to check, accepting only 1 or greater as valid input, and assign to variable "MB"
MB=0
until [ $MB -ge 1 2>/dev/null ]; do
    echo -e "\nHow many megabytes to check from the beginning, middle, and end of the disk?"
    read MB
done

# convert MBs to bytes and assign to variable "BYTES2CHK"
BYTES2CHK=$((MB * 1048576))

# get the number of bytes via diskutil, stripping leading "(", and assign to variable "BYTES"
BYTES=`diskutil info $DISK2CHK | awk '/Total\ Size/ {sub(/\(/, x); print $5}'`

# let the user know how many bytes the disk has
echo -e "\n$DISK2CHK has" $BYTES "bytes.\n"

# check beginning of disk. (-Ad = decimal; Nx = dump at most x bytes)
echo "The first $BYTES2CHK bytes:"
od -Ad -N$BYTES2CHK $DISK2CHK

# check middle of disk. (-jx = skip x bytes)
echo -e "\n$BYTES2CHK bytes from the middle:"
# divide $BYTES by 2 and assign result to variable "MIDDLEOFDISK"
MIDDLEOFDISK=`expr $BYTES / 2`
od -Ad -j$MIDDLEOFDISK -N$BYTES2CHK $DISK2CHK

# check end of disk:
echo -e "\nAnd the final $BYTES2CHK bytes:"
# subtract BYTES2CHK from BYTES and assign to variable "ENDOFDISK"
ENDOFDISK=$((BYTES - BYTES2CHK))
od -Ad -j$ENDOFDISK $DISK2CHK

And the other for Linux:

#!/bin/bash

# zerocheck.sh - check the beginning, middle, and end of a drive for zeros.
# "when you don't have the time or interest for a full hexdump"

# tested under:
# lubuntu 12.10 (though any distro with util-linux 2.19 or higher should work)

echo -e "\nzerocheck.sh - check disk for zeros\n"

# check os, display block devices, assign user's choice to variable "DISK2CHK"
if [ "$(uname)" == "Linux" ]; then
    lsblk
    echo "Enter disk to check (e.g., /dev/sdc)"
    read DISK2CHK
else
    echo "This script has only been tested under Linux."
    exit 1
fi

# ask for MBs to check, accepting only 1 or greater as valid input, and assign to variable "MB"
MB=0
until [ $MB -ge 1 2>/dev/null ]; do
    echo -e "\nHow many megabytes to check from the beginning, middle, and end of the disk?"
    read MB
done

# convert MBs to bytes and assign to variable "BYTES2CHK"
BYTES2CHK=$((MB * 1048576))

# get the number of bytes via lsblk and assign to variable "BYTES"
BYTES=`lsblk -b $DISK2CHK | awk 'NR==2 {print $4}'`

# let the user know how many bytes the disk has
echo -e "\n$DISK2CHK has" $BYTES "bytes.\n"

# check beginning of disk. (-Ad = decimal; Nx = dump at most x bytes)
echo "The first $BYTES2CHK bytes:"
od -Ad -N$BYTES2CHK $DISK2CHK

# check middle of disk. (-jx = skip x bytes)
echo -e "\n$BYTES2CHK bytes from the middle:"
# divide $BYTES by 2 and assign result to variable "MIDDLEOFDISK"
MIDDLEOFDISK=`expr $BYTES / 2`
od -Ad -j$MIDDLEOFDISK -N$BYTES2CHK $DISK2CHK

# check end of disk:
echo -e "\nAnd the final $BYTES2CHK bytes:"
# subtract BYTES2CHK from BYTES and assign to variable "ENDOFDISK"
ENDOFDISK=$((BYTES - BYTES2CHK))
od -Ad -j$ENDOFDISK $DISK2CHK

The script can be tested on an image file:

  1. Create a file filled with zeros:
    $ dd if=/dev/zero of=/path/to/zeros.img count=16384
  2. Assign it to a loopback device:
  3. Test the script:
    $ zerocheck.sh
  4. Don't forget to remove the device when done:

/nix | Jan 26, 2014


Subscribe or visit the archives.