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