dd'ing and printing progress (a lame script I wrote for something I do a lot...)

By thomas, 13 June, 2012

I often use dd to copy large files or make images from hard drives. It's annoying to watch something without any progress indicator, so I use the little known kill switch on dd.

From the man page:

Sending a USR1 signal to a running ‘dd’ process makes it print I/O statistics to standard error and then resume copying.

$ dd if=/dev/zero of=/dev/null& pid=$!
$ kill -USR1 $pid; sleep 1; kill $pid

I'll often make a for loop and keep killing dd to get the stats, I decided to make a little script to do the whole thing in one, making it even lazier...


#!/bin/bash

# run dd and kill with USR1 every 5 seconds.

term_dd() {
echo "killing dd"
kill $dd
exit 1
}

trap term_dd SIGINT SIGTERM

args=("$@")

if [ ${#args} -lt 2 ]; then
echo "usage: $0 infile outfile [other options]"
exit
fi

tmp=$(mktemp /tmp/ddk.XXXXXXXX)

echo dd if=$1 of=$2 ${args[@]:2}
dd if=$1 of=$2 ${args[@]:2} >$tmp 2>&1 &
dd=$!
echo "dd if=$1 of=$2 ${args[@]:2} $dd"
sleep 1
while /bin/true
do
if [ -d /proc/$dd ];
then
kill -USR1 $dd
else
echo "no dd $dd"
break
fi
clear
echo "dd if=$1 of=$2 ${args[@]:2}"
tail -3 $tmp
sleep 1
done
rm $tmp
exit

The only caveat here is that the sleep right before starting the while loop appears to be necessary, without it, the whole thing won't work sometimes, I can't quite figure out why...The $! doesn't seem to be populated quick enough and the script dies at that point since the first kill files to find the /proc/$! directory.