Robb Matzke wrote: > I'm actually not concerned with the SIGPIPE and expect it. What concerns me > is that the final counts reported by *dd* are wrong. It should report 1024 > records copied, but instead reports a seemingly random and variable amount. > > Why is dd closing its stdin earlier than I asked it to? Why is dd transfering > a random amount of data?
You chose a block size of 1MB. That is way larger than will ever be filled via a pipe, so every read gets a partial "block". dd stops after 1024 of those. The output you see, 0+1024 records in 0+1024 records out 4259840 bytes (4.3 MB) copied, 0.00729445 s, 584 MB/s tells you that there were 0 full blocks read and 1024 partials. ... >> > cat /dev/zero |dd bs=1MB count=1024 of=/dev/null >> > cat /dev/null |dd bs=1MB count=1024 >/dev/null >> > >> > An strace on dd shows that the last read/write pair both succeed and then >> > dd >> > inexplicably closes both files. None of the reads return zero or failure. >> > An strace on cat shows that its last write to stdout gets a sigpipe, so it >> > really is trying to send the data to dd and it's dd that's closing the >> > pipe. >> >> That's expected and in fact required. >> You're telling dd to exit after reading 1024*1MB. >> Once dd exits, it closes its side of the pipe, but cat is still writing >> to the other end. Writing to a closed pipe provokes a SIGPIPE, by default. >> How much cat actually writes before it's killed by the >> SIGPIPE depends on kernel buffering, hence the variability. >> >> > Replacing /dev/null with a real file exhibits the behavior one would >> > expect. >> > Substituting some other I/O-counting command for dd works fine.