I've not used dd all that much, but so far it's not failed me yet. Right now, I've had a dd going for over 12 hours - I'm writing an image back to the disk it came from - and I'm getting a little worried, as I was able to dd from the disk to the image in about 7 hours.

I'm running OSX 10.6.6 on a MacBook with a Core 2 Duo at 2.1ghz/core with 4gb RAM. I'm reading from a .dmg on a 7200rpm hard drive (the boot drive), and I'm writing to a 7200rpm drive connected over a SATA-to-USB connector. I left the blocksize at default, and the image is about 160gb.

EDIT: And, after 14 hours of pure stress, the dd worked perfectly after all. Next time, though, I'm going to run it through pv and track it with strace. Thanks to everyone for all your help.

Not answering your question, but your times are quite high IMO. Did you remember to pass a bigger block size to dd other than the default 512 bytes? dd ... bs=16M is my suggestion, given your RAM, disk size and speed.
– JulianoApr 13 '11 at 20:29

I didn't, simply because I wanted to play it safe. I'll try that next time, though. Thanks.
– eckzaApr 14 '11 at 1:26

In my experience, dd on Mac OS X has a tendency to freeze to the point where I can't even kill the process, but have to restart the system. I resort to doing work on a Linux VM then.
– sscJun 12 '14 at 18:58

Oh, very cool. You can combine those with pkill -USR1 -x dd
– Michael Mrozek♦Apr 13 '11 at 17:26

9

@kivetros: On BSD systems, you need to send the INFO signal. Linux doesn't have a SIGINFO and uses USR1 instead.
– GillesApr 13 '11 at 18:50

5

The SIGUSRx signals are for programs to do what they want with, as opposed to having a standardized meaning. SIGWINCH, for example, is raised when the terminal has changed its size and the program might need to redraw its screen. The operating system doesn't send SIGUSRx's so they are available for custom uses.
– LawrenceCApr 14 '11 at 1:17

11

Sending dd the USR1 signal too soon after it has started (i.e. in a bash script, the line after you started it) will in fact terminate it. Put a 0.1 second sleep in between and it will output its progress properly. By the way, a very nice dd command to test USR1/INFO on is dd if=/dev/zero of=/dev/null. :)
– Lauritz V. ThaulowApr 14 '11 at 8:51

11

BTW, all "true" BSDs send SIGINFO to foreground process group if status character (Ctrl+T by default) is sent to terminal. But I don't know whether is it true for MacOSX.
– NetchNov 1 '12 at 20:14

For next time, you can just use pv from the start (if it's available through your package manager, install it). This is a utility with the sole purpose of piping input to output and monitoring progress and speed.

It really doesn't matter what order you do dd and pv in, it's entirely performance-related -- if the device you are reading to or from has optimal performance for certain blocksizes you want to use dd instead of pv to access that device. You can even stick a dd on both ends if you want, or not at all if you don't care:

Sometimes you may not be able to use the INFO or USR1 signal because the stderr stream of the dd process is not accessible (e.g. because the terminal in which it was executed was already closed). In this case, a workaround is to do the following (tested on FreeBSD, may be slightly different on Linux):

Use iostat to estimate the average write rate (MB/s) to the target device, e.g.:

iostat -d -w30 ada0

Substitute your target device name for ada0 here, and wait a minute for it to give a couple results. The "w" parameter determines how many seconds between samples. Increasing it will give a better average estimate with less variance, but you'll have to wait longer.

Use ps to determine how long dd has been running:

ps -xo etime,command | grep dd

Convert this to seconds to get total seconds of runtime.

Multiply total seconds of runtime by average write rate to get total transferred MB.

Get the device size in MB with:

grep ada0 /var/run/dmesg.boot

Substitute your target device name for ada0. Divide the result by the average write rate to get the total transfer time in seconds. Subtract the time it's been running so far to get time remaining.

This strategy only works if dd has been writing continuously at the current average write rate since it began. If other processes are competing for the CPU or I/O resources (including the I/O bus) then it may reduce the transfer rate.

The wchar line (written characters) in /proc/$pid/io can give you precise information about the dd process. As long as it changes, your dd is still working!

Here is a neat little php script, which you can save and then execute with php filename.php during the dd to display the written bytes. The nice benefit of watching /proc/$pid/io over kill -USR1 $(pidof dd) is that you do not have to switch between terminals, which is not always an option.

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).