#!/bin/bash # search disk for a string and output commands to dump matching sections # License: LGPLv2 # Author: # http://www.pixelbeat.org/ # Notes: # On my Fedora 8 system members of the "disk" group are # allowed to read the disk devices, so to do that: # sudo /usr/sbin/usermod -a -G "disk" $USER # sudo su - $USER # Changes: # V0.1, 20 Apr 2008, Initial release # V0.3, 29 Sep 2010 # http://github.com/pixelb/scripts/commits/master/scripts/disk_grep usage() { echo "Usage: $(basename $0) file|device string" >&2 exit 1 } COLUMNS=$(tput cols) #pass % complete progress() { DONE=$(( (($COLUMNS-2)*$1)/100 )) TODO=$(($COLUMNS-2-$DONE)) DONE=$(printf "%${DONE}s" | tr ' ' =) TODO=$(printf "%${TODO}s" | tr ' ' -) printf "[$DONE$TODO]\r" > /dev/tty } #pass strings to stdout print() { CLEAR=$(printf "%${COLUMNS}s") printf "$CLEAR\r" echo "$@" } [ $# -ne 2 ] && usage DISK="$1" STRING="$2" export LANG=C # Note we must manage these limits ourselves # because dd currently does not fail if you seek # past the end of a file or device. In fact for devices # it reads the whole device when you do this! # # This also allows us to show completion progress CHUNK_SIZE=$((8*1024*1024)) if [ -b "$DISK" ]; then SIZE=$(/sbin/blockdev --getsize64 $DISK) || exit $? #reads from disk? else SIZE=$(stat --format %s "$DISK") || exit $? fi [ $SIZE -eq 0 ] && exit CHUNKS=$((($SIZE+$CHUNK_SIZE-1)/$CHUNK_SIZE)) i=0 while true; do progress $(($i*100/$CHUNKS)) [ "$i" -ge "$CHUNKS" ] && break # use "direct" flag so cache not polluted with read data dd if=$DISK iflag=direct conv=noerror bs=$CHUNK_SIZE count=1 skip=$i 2>/dev/null | #we ensure grep reads all data, otherwise dd will get SIGPIPE and exit with 141 grep --binary-files=text -U -F "$STRING" >/dev/null status=$(echo ${PIPESTATUS[@]}) dd_status=$(echo $status | cut -f1 -d ' ') re_status=$(echo $status | cut -f2 -d ' ') [ $dd_status -ne 0 ] && { echo "dd error" >&2; exit $dd_status; } [ $re_status -eq 0 ] && { print "dd if=$DISK iflag=direct bs=$CHUNK_SIZE count=1 skip=$i > disk_grep.$i"; } i=$(($i+1)) done echo