[clug] 'dd' command detecting EOF: an example script

steve jenkin sjenkin at canb.auug.org.au
Tue May 14 23:43:28 UTC 2019


This ‘feature’ of ‘dd’ (or lack of) has bugged me for a while…

The only way to detect EOF I found on-line was to look at its output…
Messy and probably fails on multiple edge conditions.

Why do I want to do this?

I’d like to run a command on each 32k block of a file, the only way I could think of, without writing some code, was to use ‘dd’.
[Saw this done once to break a tar file into pieces to fit on floppy disks. Hadn’t remembered how the loop terminated.]

If anyone has a better, or newer, way to do this, I’d appreciate suggestions.

steve

==============

Refs

Learn The DD Command Revised
https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/

Advanced Bash-Scripting Guide
	An in-depth exploration of the art of shell scripting
http://www.tldp.org/LDP/abs/html/abs-guide.html

==============
--
Steve Jenkin, IT Systems and Design 
0412 786 915 (+61 412 786 915)
PO Box 38, Kippax ACT 2615, AUSTRALIA

mailto:sjenkin at canb.auug.org.au http://members.tip.net.au/~sjenkin

———————————oooOooo———————————

#!/bin/sh
# ~/bin/dd_eof	- EXAMPLE deblocking a file with 'dd', running it through a command and detecting EOF
#		I consider 'dd' behaviour in error - reading from an empty or closed pipe, it should exit with an error, not copy zero bytes, infinitely
#		currently 'dd' only reports IO errors (disk full, read/write error, ...)
# Steve Jenkin Wed 15 May 2019 08:06:52 AEST

# NOTE: assumes you want to output to 'STDOUT'.

DEBUG=2		# turn debugging ON, more verbose
DEBUG=1		# turn debugging ON
DEBUG=		# zero or unset, turn debugging OFF

Tmp_EOF=$(mktemp)				# takes a little time, but should be safe, writable and free of side-effects
trap "[ -n "$DEBUG" ] && echo ${Tmp_EOF}; /bin/rm ${Tmp_EOF}" 0 HUP TERM		# attempt to cleanup temp file.

# No 'usage' or 'help' function included, as a live script should have... 

######### setup script variables #########

# NO error checking done
# in a live script, *extreme* danger from running unchecked 'Cmd' variable.

Ifile="${1:-t.0}"
Cmd="${2:-/bin/cat}"
Blk_sz="${3:-32k}"
Count="${4:-1}"

######### start script proper #########

if [[ ! -f "${Ifile}" ]] || [[ ! -r "${Ifile}" ]]
then
    echo "Can't read ${Ifile}" >&2
    exit 1
fi

[[ "$DEBUG" -gt 1 ]] && set -x	# turn on debugging for the loop
set -o pipefail			# ask shell to report _any_ non-zero exit from pipelines, not just last executed cmd (right most)
				# 'dd' _does_ exit with IO errors, want to catch them on input or output, though 'STDOUT' is redirected outside this script

# the 'dd' feeding the file into 'while' isn't checked for errors (a limitation in production)
# 'dd' is used because 'cat' doesn't always push large blocks, confusing the EOF test and ending on 1st read.
# if rewriting this script for pipeline use, remove 'Ifile' and the 'dd' feeding the while loop.

n=0
dd bs="${Blk_sz}" if="${Ifile}" 2>/dev/null |\
    while dd count="${Count}" bs="${Blk_sz}" 2>"${Tmp_EOF}" | ${Cmd} 2>/dev/null 
    do
	x=$?			# for debugging, remember pipeline return status.
	n=$(( $n + 1 ))		# count blocks
	[[ -n "$DEBUG" ]] && echo "status: $x blk: $n" >&2	# or '>/dev/null' for nothing

	# check Temp file for indicator of EOF.
	# first extract single line - could've been 'head -1', but that assumes nothing went wrong & added other lines to STDERR
	# then check if a full block was found
	if grep -e ' records in$' "${Tmp_EOF}" | grep -q -v -e "^${Count}+0 records in"
	then
	    [[ -n "$DEBUG" ]] && echo "dd exit status $?" >&2
	    break
	fi
    done			# writes to 'STDOUT', could be captured.

exit

set +x	# turn off debugging after the loop

##################################3

Refs

Learn The DD Command Revised
https://www.linuxquestions.org/questions/linux-newbie-8/learn-the-dd-command-362506/

Advanced Bash-Scripting Guide
	An in-depth exploration of the art of shell scripting
http://www.tldp.org/LDP/abs/html/abs-guide.html


———————————oooOooo———————————





More information about the linux mailing list