ddwrapper¶
Wrapper Script for dd.
This is a simple wrapper script for dd. It runs dd and displays the progress (total transferred and average speed). The status update rate is configurable with the -d flag. It accepts all parameters dd would accept too. Reading from or writing to stdout is not possible with this version.
#!/bin/bash
#
# $Id: dd.sh,v 1.6 2007/03/01 16:11:37 flip Exp $
#
# Copyright (c) 2006, 2007 Philippe Kehl <phkehl at gmx dot net>
#
# dd.sh -- dd wrapper script to display progress and speed
#
# This is Free Software blabla etc.
#
DD=${DD:-dd}
DEBUG=${DEBUG:-}
delay=1
function usage()
{
echo "Usage: [DEBUG=1] [DD=/path/to/dd] ${0##*/} [-d <delay>] \"
echo " if=.. of=.. [ibs=.. obs=.. |bs=..] [skip=..] [count=..] [..]"
exit 1
}
# get command line parameters
[ $# -lt 2 ] && usage
while [ "${1:0:1}" = "-" ]; do
echo "loop1"
case $1 in
-d)
delay=$2;
shift
;;
*)
echo "Error: Unknown flag $1."
exit 1
;;
esac
shift
done
[ $# -lt 2 ] && usage
while [ ! -z $1 ]; do
k=${1%%=*}
v=${1##*=}
case $k in
"if")
p_if=$v
;;
of)
p_of=$v;
of_dir=${p_of%/*}/
[[ $of_dir = $p_of/ ]] && of_dir=./
;;
bs)
p_bs=$v
;;
obs)
p_obs=$v;
;;
ibs)
p_ibs=$v;
;;
cbs)
p_cbs=$v;
;;
conv)
p_conv=$v;
;;
count)
p_count=$v;
;;
seek)
p_seek=$v;
;;
skip)
p_skip=$v;
;;
esac
shift
done
# check parameters
[[ -z $p_if || -z $p_of ]] &&
{ echo "Error: Both if and of are mandatory."; exit 1; }
[[ ! -z $p_bs && ( ! -z $p_obs || ! -z $p_ibs ) ]] &&
{ echo "Error: Do not mix bs with ibs or obs."; exit 1; }
[[ ( -z $p_obs && ! -z $p_ibs ) || ( -z $p_ibs && ! -z $p_obs) ]] &&
{ echo "Error: Specify both ibs and obs."; exit 1; }
[[ ! -r $p_if ]] &&
{ echo "Error: Cannot read from $p_if."; exit 1; }
[[ -e $p_of && ! -w $p_of ]] &&
{ echo "Error: Cannot write to $p_of."; exit 1; }
[[ ! -e $p_of && ! -w $of_dir ]] &&
{ echo "Error: Cannot write in $of_dir (or $p_of does not exist)."; exit 1; }
# combine parameters for dd
dd_arg=
for p in ${!p_*}; do
eval dd_arg=""$dd_arg ${p#*_}=$$p""
done
[ ! -z $DEBUG ] && echo "dd_arg=$dd_arg"
# create a fifo to watch dd output
while true; do
dd_out=/tmp/${0##*/}-$RANDOM.tmp
[ ! -e $dd_out ] && { mkfifo -m 600 $dd_out; break; }
done
[ ! -z $DEBUG ] && echo "dd_out=$dd_out"
# run dd
LC_ALL=C dd $dd_arg 2> $dd_out &
dd_pid=$!
[ ! -z $DEBUG ] && echo "dd_pid=$dd_pid"
# create a trap to abort dd nicely
abort=0
function abortdd()
{
abort=1
echo
echo -n "Aborting "
while [ -d /proc/$dd_pid ]; do
echo -n "."
#kill -SIGINT $dd_pid # FIXME: why does this not work?
kill $dd_pid
sleep 1
done
echo " done."
abort=2
}
trap abortdd SIGINT SIGKILL SIGHUP
# redirect errors
exec 2>/dev/null
# routine to convert bytes mb
function b2mb()
{
local m
m=$(($1*100/1024/1024))
m=${m:0:$((${#m}-2))}.${m: -2}
echo $m
}
# watch dd output
while [ $abort -eq 0 ]; do
sleep $delay
[ $abort -eq 1 ] && continue
[ $abort -eq 2 ] && break
kill -SIGUSR1 $dd_pid
read l1
read l2
read l3
#echo $l1 " / " $l2 " / " $l3
# convert bytes per second to mb per second
bps=${l3##*(}; bps=${bps%% *}
mps=$(b2mb $bps)
b=${l3%% bytes *}
m=$(b2mb $b)
t=${l3##* transferred in }; t=${t%%.*};
echo -ne "rStatus: $l1, $l2, $m MB transferred in $t seconds ($mps MB/sec)"
#[ $abort -eq 2 ] && break
done < $dd_out
rm -f $dd_out
#eof
created: 2008-04-05, updated: 2015-10-10