Sample Header Ad - 728x90

How do I find the first non-zero byte on a block device, with an optional offset?

11 votes
2 answers
2798 views
I'm trying to find the first non-zero byte (starting from an optional offset) on a block device using dd and print its offset, but I am stuck. I didn't mention dd in the title as I figured there might be a more appropriate tool than dd to do this, but I figured dd should be a good start. If you know of a more appropriate tool and/or more efficient way to reach my goal, that's fine too. In the meantime I'll show you how far I've come with dd in bash, so far.
#!/bin/bash

# infile is just a temporary test file for now, which will be replaced with /dev/sdb, for instance
infile=test.txt
offset=0

while true; do
  byte=dd status='none' bs=1 count=1 if="$infile" skip=$offset
  ret=$?

  # the following doesn't appear to work
  # ret is always 0, even when the end of file/device is reached
  # how do I correctly determine if dd has reached the end of file/device?
  if [ $ret -gt 0 ]; then
    echo 'error, or end of file reached'
    break
  fi

  # I don't know how to correctly determine if the byte is non-zero
  # how do I determine if the read byte is non-zero?
  if [ $byte ???? ]; then
    echo "non-zero byte found at $offset"
    break
  fi

  ((++offset))
done
As you can see, I'm stuck with two issues that I don't know how to solve: a. How do I make the while loop break when dd has reached the end of the file/device? dd gives an exit code of 0, where I expected a non-zero exit code instead. b. How do I evaluate whether the byte that dd read and returns on stdout is non-zero? I think I've read somewhere that special care should be taken in bash with \0 bytes as well, but I'm not even sure this pertains to this situation. Can you give me some hints on how to proceed, or perhaps suggest and alternative way to achieve my goal?
Asked by ExploringQuest (113 rep)
Jun 1, 2021, 01:01 PM
Last activity: Jun 2, 2021, 10:53 PM