The dd command is a tool used to pipe data in from a source to a destination. It has a multitude of uses ranging from creating large dummy files of a specific size to duplicating hard-drives sector by sector to another disk or to a backup file. It’s also useful for fixing problems with hard-drives that Windows refuses to deal with.
But we’re not looking at the virtues of dd here. We’re looking at its annoyances and dd has one particularly glaring annoyance – a lack of display of progress. You could tell dd to start imaging your multi-terabyte hard-drive and not have any indication of how far it has gone – you just have to wait until it finishes. The dd command only outputs some information right at the very end of its job, which could well be several hours later. The only indicator that you have that something is happening is your hard-drive light madly flashing away.
Luckily while dd doesn’t show progress during its tasks, it can be prodded externally to give up information about itself as it runs, and we can achieve that by using the kill command without actually killing the dd command’s execution.
Now the kill command doesn’t just terminate tasks. It can also send other standard POSIX signals to applications. Many applications are written to acknowledge certain signals and perform an action on receiving them. In the case of dd, there is one signal that will make it output its summary information to the console as though it had finished, but rather than terminate, it keeps on going. The signal in question is USR1.
Here’s how to make use of it:
- First we need a dd process running. Let’s say we are imaging our first fixed hard-drive /dev/sda to an image file called MyHDDBackup.img using the following command:
$ sudo dd if=/dev/sda of=/home/jbloggs/MyHDDBackup.img
- Now while that is running, open up a second terminal and type in the following followed by Enter:
$ sudo kill -USR1 `pgrep ^dd`
Breakdown of the above command:
- sudo runs this command as root. In this case since we’re using dd as root, we also need to run the kill command as root or we won’t be able to send anything to dd.
- kill is the command we are using to send dd a signal with.
- -USR1 is the signal we are sending to dd.
- pgrep is a program that will show you the process ID of a given application, in this case we use the argument “^dd” to say “locate any program that starts with the text ‘dd’ only” otherwise we would get other processes that containg the letters “dd” together in their name if we left out the chevron character. Note that the pgrep command is enclosed in “`” quotes so that it is executed and returns just a process ID number to the kill command.
- Now have a look at the terminal that dd is running in. It has suddenly output some data about itself, specifically, how much of the task had been completed, but dd is still running!
This is great – but how can we regularly have dd tell us where it’s up to without having to manually enter the above command each time? Simple, by combining it with the watch command:
$ watch 'sudo kill -USR1 `pgrep ^dd`'
The watch command will will re-execute the kill command once every two seconds, giving you near-realtime status to what dd is doing. If you want to change how often the watch command polls for, you can change it with the -n parameter, for example to change the polling to every 5 seconds, you would use:
$ watch -n5 'sudo kill -USR1 `pgrep ^dd`'
While not providing any means of showing you how long it will take for dd to ultimately finish, you can now make use of the transfer speed shown along with the data processed thus far and calculate a rough idea of when dd will complete its task now.
Pat yourself on the back. You can now rest easy knowing that you can find out at anytime where dd is up to.