#!/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 proc usage { echo "Usage: $[basename $0] file|device string" > !2 exit 1 } global COLUMNS := $[tput cols] #pass % complete proc progress { global DONE := $( (($COLUMNS-2)*$1)/100 ) global TODO := $($COLUMNS-2-$DONE) global DONE := $[printf "%$(DONE)s" | tr ' ' =] global TODO := $[printf "%$(TODO)s" | tr ' ' -] printf "[$DONE$TODO]\r" > /dev/tty } #pass strings to stdout proc print { global CLEAR := $[printf "%$(COLUMNS)s] printf "$CLEAR\r" echo @Argv } test $Argc -ne 2 && usage global DISK := $1 global 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 global CHUNK_SIZE := $(8*1024*1024) if test -b $DISK { global SIZE := $[/sbin/blockdev --getsize64 $DISK] || exit $Status #reads from disk? } else { global SIZE := $[stat --format %s $DISK] || exit $Status } test $SIZE -eq 0 && exit global CHUNKS := $(($SIZE+$CHUNK_SIZE-1)/$CHUNK_SIZE) global i := '0' while true { progress $($i*100/$CHUNKS) test $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 global status := $[echo $(PIPESTATUS[@])] global dd_status := $[echo $status | cut -f1 -d ' ] global re_status := $[echo $status | cut -f2 -d ' ] test $dd_status -ne 0 && do { echo "dd error" > !2; exit $dd_status; } test $re_status -eq 0 && do { print "dd if=$DISK iflag=direct bs=$CHUNK_SIZE count=1 skip=$i > disk_grep.$i"; } global i := $($i+1) } echo (CommandList children: [ (FuncDef name: usage body: (BraceGroup children: [ (SimpleCommand words: [ {(echo)} { (DQ ("Usage: ") (CommandSubPart command_list: (CommandList children:[(C {(basename)} {($ VSub_Number "$0")})]) left_token: spids: [56 60] ) (" file|device string") ) } ] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[64])] ) (C {(exit)} {(1)}) ] spids: [49] ) spids: [45 48] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:COLUMNS) op: Equal rhs: { (CommandSubPart command_list: (CommandList children:[(C {(tput)} {(cols)})]) left_token: spids: [76 80] ) } spids: [75] ) ] spids: [75] ) (FuncDef name: progress body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DONE) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithBinary op_id: Arith_Star left: (ArithBinary op_id: Arith_Minus left: (ArithWord w:{($ VSub_Name "$COLUMNS")}) right: (ArithWord w:{(Lit_Digits 2)}) ) right: (ArithWord w:{($ VSub_Number "$1")}) ) right: (ArithWord w:{(Lit_Digits 100)}) ) spids: [94 109] ) } spids: [93] ) ] spids: [93] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:TODO) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Minus left: (ArithBinary op_id: Arith_Minus left: (ArithWord w:{($ VSub_Name "$COLUMNS")}) right: (ArithWord w:{(Lit_Digits 2)}) ) right: (ArithWord w:{($ VSub_Name "$DONE")}) ) spids: [113 120] ) } spids: [112] ) ] spids: [112] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DONE) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(printf)} {(DQ ("%") (${ VSub_Name DONE) (s))}) (C {(tr)} {(SQ <" ">)} {(Lit_Other "=")}) ] negated: False ) ] ) left_token: spids: [124 144] ) } spids: [123] ) ] spids: [123] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:TODO) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(printf)} {(DQ ("%") (${ VSub_Name TODO) (s))}) (C {(tr)} {(SQ <" ">)} {(-)}) ] negated: False ) ] ) left_token: spids: [148 168] ) } spids: [147] ) ] spids: [147] ) (SimpleCommand words: [ {(printf)} { (DQ ("[") ($ VSub_Name "$DONE") ($ VSub_Name "$TODO") ("]") (EscapedLiteralPart token:) ) } ] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/tty)} spids:[181])] ) ] spids: [90] ) spids: [86 89] ) (FuncDef name: print body: (BraceGroup children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:CLEAR) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [(C {(printf)} {(DQ ("%") (${ VSub_Name COLUMNS) (s))})] ) left_token: spids: [199 209] ) } spids: [198] ) ] spids: [198] ) (C {(printf)} {(DQ ($ VSub_Name "$CLEAR") (EscapedLiteralPart token:))} ) (C {(echo)} {(DQ ($ VSub_At "$@"))}) ] spids: [195] ) spids: [191 194] ) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_Pound "$#")} {(-ne)} {(2)} {(Lit_Other "]")}) (C {(usage)}) ] op_id: Op_DAmp ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:DISK) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [243] ) ] spids: [243] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:STRING) op: Equal rhs: {(DQ ($ VSub_Number "$2"))} spids: [248] ) ] spids: [248] ) (C {(export)} {(Lit_VarLike "LANG=") (C)}) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:CHUNK_SIZE) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Star left: (ArithBinary op_id: Arith_Star left: (ArithWord w:{(Lit_Digits 8)}) right: (ArithWord w:{(Lit_Digits 1024)}) ) right: (ArithWord w:{(Lit_Digits 1024)}) ) spids: [279 286] ) } spids: [278] ) ] spids: [278] ) (If arms: [ (if_arm cond: [ (Sentence child: (C {(Lit_Other "[")} {(-b)} {(DQ ($ VSub_Name "$DISK"))} {(Lit_Other "]")}) terminator: ) ] action: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SIZE) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(/sbin/blockdev)} {(--getsize64)} {($ VSub_Name "$DISK")}) ] ) left_token: spids: [305 311] ) } spids: [304] ) ] spids: [304] ) (C {(exit)} {($ VSub_QMark "$?")}) ] op_id: Op_DPipe ) ] spids: [-1 301] ) ] else_action: [ (AndOr children: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:SIZE) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(stat)} {(--format)} {(Lit_Other "%") (s)} {(DQ ($ VSub_Name "$DISK"))}) ] ) left_token: spids: [326 337] ) } spids: [325] ) ] spids: [325] ) (C {(exit)} {($ VSub_QMark "$?")}) ] op_id: Op_DPipe ) ] spids: [322 345] ) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_Name "$SIZE")} {(-eq)} {(0)} {(Lit_Other "]")}) (C {(exit)}) ] op_id: Op_DAmp ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:CHUNKS) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithBinary op_id: Arith_Minus left: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{($ VSub_Name "$SIZE")}) right: (ArithWord w:{($ VSub_Name "$CHUNK_SIZE")}) ) right: (ArithWord w:{(Lit_Digits 1)}) ) right: (ArithWord w:{($ VSub_Name "$CHUNK_SIZE")}) ) spids: [362 373] ) } spids: [361] ) ] spids: [361] ) (Assignment keyword: Assign_None pairs: [(assign_pair lhs:(LhsName name:i) op:Equal rhs:{(0)} spids:[376])] spids: [376] ) (While cond: [(Sentence child:(C {(true)}) terminator:)] body: (DoGroup children: [ (C {(progress)} { (ArithSubPart anode: (ArithBinary op_id: Arith_Slash left: (ArithBinary op_id: Arith_Star left: (ArithWord w:{($ VSub_Name "$i")}) right: (ArithWord w:{(Lit_Digits 100)}) ) right: (ArithWord w:{($ VSub_Name "$CHUNKS")}) ) spids: [389 396] ) } ) (AndOr children: [ (C {(Lit_Other "[")} {(DQ ($ VSub_Name "$i"))} {(-ge)} {(DQ ($ VSub_Name "$CHUNKS"))} {(Lit_Other "]")} ) (ControlFlow token:) ] op_id: Op_DAmp ) (Pipeline children: [ (SimpleCommand words: [ {(dd)} {(Lit_VarLike "if=") ($ VSub_Name "$DISK")} {(Lit_VarLike "iflag=") (direct)} {(Lit_VarLike "conv=") (noerror)} {(Lit_VarLike "bs=") ($ VSub_Name "$CHUNK_SIZE")} {(Lit_VarLike "count=") (1)} {(Lit_VarLike "skip=") ($ VSub_Name "$i")} ] redirects: [(Redir op_id:Redir_Great fd:2 arg_word:{(/dev/null)} spids:[442])] ) (SimpleCommand words: [ {(grep)} {(--binary-files) (Lit_Other "=") (text)} {(-U)} {(-F)} {(DQ ($ VSub_Name "$STRING"))} ] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[466])] ) ] negated: False ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:status) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (C {(echo)} { (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [474 479] ) } ) ] ) left_token: spids: [471 480] ) } spids: [470] ) ] spids: [470] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:dd_status) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$status")}) (C {(cut)} {(-f1)} {(-d)} {(SQ <" ">)}) ] negated: False ) ] ) left_token: spids: [484 500] ) } spids: [483] ) ] spids: [483] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:re_status) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$status")}) (C {(cut)} {(-f2)} {(-d)} {(SQ <" ">)}) ] negated: False ) ] ) left_token: spids: [504 520] ) } spids: [503] ) ] spids: [503] ) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_Name "$dd_status")} {(-ne)} {(0)} {(Lit_Other "]")}) (BraceGroup children: [ (Sentence child: (SimpleCommand words: [{(echo)} {(DQ ("dd error"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:-1 arg_word:{(2)} spids:[543])] ) terminator: ) (Sentence child: (C {(exit)} {($ VSub_Name "$dd_status")}) terminator: ) ] spids: [535] ) ] op_id: Op_DAmp ) (AndOr children: [ (C {(Lit_Other "[")} {($ VSub_Name "$re_status")} {(-eq)} {(0)} {(Lit_Other "]")}) (BraceGroup children: [ (Sentence child: (C {(print)} { (DQ ("dd if=") ($ VSub_Name "$DISK") (" iflag=direct bs=") ($ VSub_Name "$CHUNK_SIZE") (" count=1 skip=") ($ VSub_Name "$i") (" > disk_grep.") ($ VSub_Name "$i") ) } ) terminator: ) ] spids: [567] ) ] op_id: Op_DAmp ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:i) op: Equal rhs: { (ArithSubPart anode: (ArithBinary op_id: Arith_Plus left: (ArithWord w:{($ VSub_Name "$i")}) right: (ArithWord w:{(Lit_Digits 1)}) ) spids: [587 592] ) } spids: [586] ) ] spids: [586] ) ] spids: [384 594] ) ) (C {(echo)}) ] )